ci: package dependencies in actions/retest

these dependencies were not updated and this commit update the
same.

Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
Humble Chirammal 2022-11-11 19:00:05 +05:30 committed by mergify[bot]
parent 71c4ae542c
commit a2215683e1
105 changed files with 9300 additions and 2851 deletions

View File

@ -1,16 +1,16 @@
module github.com/ceph/ceph-csi/actions/retest module github.com/ceph/ceph-csi/actions/retest
go 1.17 go 1.18
require ( require (
github.com/google/go-github v17.0.0+incompatible github.com/google/go-github v17.0.0+incompatible
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 golang.org/x/oauth2 v0.2.0
) )
require ( require (
github.com/golang/protobuf v1.4.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect golang.org/x/net v0.2.0 // indirect
google.golang.org/appengine v1.6.6 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.25.0 // indirect google.golang.org/protobuf v1.28.1 // indirect
) )

View File

@ -1,367 +1,28 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -13,6 +13,7 @@ import (
"strings" "strings"
"sync" "sync"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/runtime/protoimpl" "google.golang.org/protobuf/runtime/protoimpl"
@ -62,14 +63,7 @@ func FileDescriptor(s filePath) fileDescGZIP {
// Find the descriptor in the v2 registry. // Find the descriptor in the v2 registry.
var b []byte var b []byte
if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil { if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil {
if fd, ok := fd.(interface{ ProtoLegacyRawDesc() []byte }); ok { b, _ = Marshal(protodesc.ToFileDescriptorProto(fd))
b = fd.ProtoLegacyRawDesc()
} else {
// TODO: Use protodesc.ToFileDescriptorProto to construct
// a descriptorpb.FileDescriptorProto and marshal it.
// However, doing so causes the proto package to have a dependency
// on descriptorpb, leading to cyclic dependency issues.
}
} }
// Locally cache the raw descriptor form for the file. // Locally cache the raw descriptor form for the file.

View File

@ -765,7 +765,7 @@ func unescape(s string) (ch string, tail string, err error) {
if i > utf8.MaxRune { if i > utf8.MaxRune {
return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
} }
return string(i), s, nil return string(rune(i)), s, nil
} }
return "", "", fmt.Errorf(`unknown escape \%c`, r) return "", "", fmt.Errorf(`unknown escape \%c`, r)
} }

View File

@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

View File

@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.7
// +build go1.7 // +build go1.7
package context package context
@ -31,7 +32,7 @@ var DeadlineExceeded = context.DeadlineExceeded
// call cancel as soon as the operations running in this Context complete. // call cancel as soon as the operations running in this Context complete.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
ctx, f := context.WithCancel(parent) ctx, f := context.WithCancel(parent)
return ctx, CancelFunc(f) return ctx, f
} }
// WithDeadline returns a copy of the parent context with the deadline adjusted // WithDeadline returns a copy of the parent context with the deadline adjusted
@ -45,7 +46,7 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
// call cancel as soon as the operations running in this Context complete. // call cancel as soon as the operations running in this Context complete.
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
ctx, f := context.WithDeadline(parent, deadline) ctx, f := context.WithDeadline(parent, deadline)
return ctx, CancelFunc(f) return ctx, f
} }
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.9
// +build go1.9 // +build go1.9
package context package context

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package context package context

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !go1.9
// +build !go1.9 // +build !go1.9
package context package context

View File

@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

View File

@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

View File

@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at https://tip.golang.org/AUTHORS.

View File

@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at https://tip.golang.org/CONTRIBUTORS.

View File

@ -6,7 +6,6 @@ package prototext
import ( import (
"fmt" "fmt"
"strings"
"unicode/utf8" "unicode/utf8"
"google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/messageset"
@ -18,11 +17,12 @@ import (
"google.golang.org/protobuf/internal/set" "google.golang.org/protobuf/internal/set"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
// Unmarshal reads the given []byte into the given proto.Message. // Unmarshal reads the given []byte into the given proto.Message.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func Unmarshal(b []byte, m proto.Message) error { func Unmarshal(b []byte, m proto.Message) error {
return UnmarshalOptions{}.Unmarshal(b, m) return UnmarshalOptions{}.Unmarshal(b, m)
} }
@ -51,8 +51,9 @@ type UnmarshalOptions struct {
} }
} }
// Unmarshal reads the given []byte and populates the given proto.Message using options in // Unmarshal reads the given []byte and populates the given proto.Message
// UnmarshalOptions object. // using options in the UnmarshalOptions object.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error { func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
return o.unmarshal(b, m) return o.unmarshal(b, m)
} }
@ -102,7 +103,7 @@ func (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
} }
// unmarshalMessage unmarshals into the given protoreflect.Message. // unmarshalMessage unmarshals into the given protoreflect.Message.
func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error {
messageDesc := m.Descriptor() messageDesc := m.Descriptor()
if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
return errors.New("no support for proto1 MessageSets") return errors.New("no support for proto1 MessageSets")
@ -149,34 +150,24 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error {
} }
// Resolve the field descriptor. // Resolve the field descriptor.
var name pref.Name var name protoreflect.Name
var fd pref.FieldDescriptor var fd protoreflect.FieldDescriptor
var xt pref.ExtensionType var xt protoreflect.ExtensionType
var xtErr error var xtErr error
var isFieldNumberName bool var isFieldNumberName bool
switch tok.NameKind() { switch tok.NameKind() {
case text.IdentName: case text.IdentName:
name = pref.Name(tok.IdentName()) name = protoreflect.Name(tok.IdentName())
fd = fieldDescs.ByName(name) fd = fieldDescs.ByTextName(string(name))
if fd == nil {
// The proto name of a group field is in all lowercase,
// while the textproto field name is the group message name.
gd := fieldDescs.ByName(pref.Name(strings.ToLower(string(name))))
if gd != nil && gd.Kind() == pref.GroupKind && gd.Message().Name() == name {
fd = gd
}
} else if fd.Kind() == pref.GroupKind && fd.Message().Name() != name {
fd = nil // reset since field name is actually the message name
}
case text.TypeName: case text.TypeName:
// Handle extensions only. This code path is not for Any. // Handle extensions only. This code path is not for Any.
xt, xtErr = d.findExtension(pref.FullName(tok.TypeName())) xt, xtErr = d.opts.Resolver.FindExtensionByName(protoreflect.FullName(tok.TypeName()))
case text.FieldNumber: case text.FieldNumber:
isFieldNumberName = true isFieldNumberName = true
num := pref.FieldNumber(tok.FieldNumber()) num := protoreflect.FieldNumber(tok.FieldNumber())
if !num.IsValid() { if !num.IsValid() {
return d.newError(tok.Pos(), "invalid field number: %d", num) return d.newError(tok.Pos(), "invalid field number: %d", num)
} }
@ -224,7 +215,7 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error {
switch { switch {
case fd.IsList(): case fd.IsList():
kind := fd.Kind() kind := fd.Kind()
if kind != pref.MessageKind && kind != pref.GroupKind && !tok.HasSeparator() { if kind != protoreflect.MessageKind && kind != protoreflect.GroupKind && !tok.HasSeparator() {
return d.syntaxError(tok.Pos(), "missing field separator :") return d.syntaxError(tok.Pos(), "missing field separator :")
} }
@ -241,7 +232,7 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error {
default: default:
kind := fd.Kind() kind := fd.Kind()
if kind != pref.MessageKind && kind != pref.GroupKind && !tok.HasSeparator() { if kind != protoreflect.MessageKind && kind != protoreflect.GroupKind && !tok.HasSeparator() {
return d.syntaxError(tok.Pos(), "missing field separator :") return d.syntaxError(tok.Pos(), "missing field separator :")
} }
@ -269,22 +260,13 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error {
return nil return nil
} }
// findExtension returns protoreflect.ExtensionType from the Resolver if found.
func (d decoder) findExtension(xtName pref.FullName) (pref.ExtensionType, error) {
xt, err := d.opts.Resolver.FindExtensionByName(xtName)
if err == nil {
return xt, nil
}
return messageset.FindMessageSetExtension(d.opts.Resolver, xtName)
}
// unmarshalSingular unmarshals a non-repeated field value specified by the // unmarshalSingular unmarshals a non-repeated field value specified by the
// given FieldDescriptor. // given FieldDescriptor.
func (d decoder) unmarshalSingular(fd pref.FieldDescriptor, m pref.Message) error { func (d decoder) unmarshalSingular(fd protoreflect.FieldDescriptor, m protoreflect.Message) error {
var val pref.Value var val protoreflect.Value
var err error var err error
switch fd.Kind() { switch fd.Kind() {
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
val = m.NewField(fd) val = m.NewField(fd)
err = d.unmarshalMessage(val.Message(), true) err = d.unmarshalMessage(val.Message(), true)
default: default:
@ -298,94 +280,94 @@ func (d decoder) unmarshalSingular(fd pref.FieldDescriptor, m pref.Message) erro
// unmarshalScalar unmarshals a scalar/enum protoreflect.Value specified by the // unmarshalScalar unmarshals a scalar/enum protoreflect.Value specified by the
// given FieldDescriptor. // given FieldDescriptor.
func (d decoder) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) { func (d decoder) unmarshalScalar(fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
tok, err := d.Read() tok, err := d.Read()
if err != nil { if err != nil {
return pref.Value{}, err return protoreflect.Value{}, err
} }
if tok.Kind() != text.Scalar { if tok.Kind() != text.Scalar {
return pref.Value{}, d.unexpectedTokenError(tok) return protoreflect.Value{}, d.unexpectedTokenError(tok)
} }
kind := fd.Kind() kind := fd.Kind()
switch kind { switch kind {
case pref.BoolKind: case protoreflect.BoolKind:
if b, ok := tok.Bool(); ok { if b, ok := tok.Bool(); ok {
return pref.ValueOfBool(b), nil return protoreflect.ValueOfBool(b), nil
} }
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
if n, ok := tok.Int32(); ok { if n, ok := tok.Int32(); ok {
return pref.ValueOfInt32(n), nil return protoreflect.ValueOfInt32(n), nil
} }
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
if n, ok := tok.Int64(); ok { if n, ok := tok.Int64(); ok {
return pref.ValueOfInt64(n), nil return protoreflect.ValueOfInt64(n), nil
} }
case pref.Uint32Kind, pref.Fixed32Kind: case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
if n, ok := tok.Uint32(); ok { if n, ok := tok.Uint32(); ok {
return pref.ValueOfUint32(n), nil return protoreflect.ValueOfUint32(n), nil
} }
case pref.Uint64Kind, pref.Fixed64Kind: case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
if n, ok := tok.Uint64(); ok { if n, ok := tok.Uint64(); ok {
return pref.ValueOfUint64(n), nil return protoreflect.ValueOfUint64(n), nil
} }
case pref.FloatKind: case protoreflect.FloatKind:
if n, ok := tok.Float32(); ok { if n, ok := tok.Float32(); ok {
return pref.ValueOfFloat32(n), nil return protoreflect.ValueOfFloat32(n), nil
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if n, ok := tok.Float64(); ok { if n, ok := tok.Float64(); ok {
return pref.ValueOfFloat64(n), nil return protoreflect.ValueOfFloat64(n), nil
} }
case pref.StringKind: case protoreflect.StringKind:
if s, ok := tok.String(); ok { if s, ok := tok.String(); ok {
if strs.EnforceUTF8(fd) && !utf8.ValidString(s) { if strs.EnforceUTF8(fd) && !utf8.ValidString(s) {
return pref.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8") return protoreflect.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8")
} }
return pref.ValueOfString(s), nil return protoreflect.ValueOfString(s), nil
} }
case pref.BytesKind: case protoreflect.BytesKind:
if b, ok := tok.String(); ok { if b, ok := tok.String(); ok {
return pref.ValueOfBytes([]byte(b)), nil return protoreflect.ValueOfBytes([]byte(b)), nil
} }
case pref.EnumKind: case protoreflect.EnumKind:
if lit, ok := tok.Enum(); ok { if lit, ok := tok.Enum(); ok {
// Lookup EnumNumber based on name. // Lookup EnumNumber based on name.
if enumVal := fd.Enum().Values().ByName(pref.Name(lit)); enumVal != nil { if enumVal := fd.Enum().Values().ByName(protoreflect.Name(lit)); enumVal != nil {
return pref.ValueOfEnum(enumVal.Number()), nil return protoreflect.ValueOfEnum(enumVal.Number()), nil
} }
} }
if num, ok := tok.Int32(); ok { if num, ok := tok.Int32(); ok {
return pref.ValueOfEnum(pref.EnumNumber(num)), nil return protoreflect.ValueOfEnum(protoreflect.EnumNumber(num)), nil
} }
default: default:
panic(fmt.Sprintf("invalid scalar kind %v", kind)) panic(fmt.Sprintf("invalid scalar kind %v", kind))
} }
return pref.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString()) return protoreflect.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString())
} }
// unmarshalList unmarshals into given protoreflect.List. A list value can // unmarshalList unmarshals into given protoreflect.List. A list value can
// either be in [] syntax or simply just a single scalar/message value. // either be in [] syntax or simply just a single scalar/message value.
func (d decoder) unmarshalList(fd pref.FieldDescriptor, list pref.List) error { func (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflect.List) error {
tok, err := d.Peek() tok, err := d.Peek()
if err != nil { if err != nil {
return err return err
} }
switch fd.Kind() { switch fd.Kind() {
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
switch tok.Kind() { switch tok.Kind() {
case text.ListOpen: case text.ListOpen:
d.Read() d.Read()
@ -459,22 +441,22 @@ func (d decoder) unmarshalList(fd pref.FieldDescriptor, list pref.List) error {
// unmarshalMap unmarshals into given protoreflect.Map. A map value is a // unmarshalMap unmarshals into given protoreflect.Map. A map value is a
// textproto message containing {key: <kvalue>, value: <mvalue>}. // textproto message containing {key: <kvalue>, value: <mvalue>}.
func (d decoder) unmarshalMap(fd pref.FieldDescriptor, mmap pref.Map) error { func (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error {
// Determine ahead whether map entry is a scalar type or a message type in // Determine ahead whether map entry is a scalar type or a message type in
// order to call the appropriate unmarshalMapValue func inside // order to call the appropriate unmarshalMapValue func inside
// unmarshalMapEntry. // unmarshalMapEntry.
var unmarshalMapValue func() (pref.Value, error) var unmarshalMapValue func() (protoreflect.Value, error)
switch fd.MapValue().Kind() { switch fd.MapValue().Kind() {
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
unmarshalMapValue = func() (pref.Value, error) { unmarshalMapValue = func() (protoreflect.Value, error) {
pval := mmap.NewValue() pval := mmap.NewValue()
if err := d.unmarshalMessage(pval.Message(), true); err != nil { if err := d.unmarshalMessage(pval.Message(), true); err != nil {
return pref.Value{}, err return protoreflect.Value{}, err
} }
return pval, nil return pval, nil
} }
default: default:
unmarshalMapValue = func() (pref.Value, error) { unmarshalMapValue = func() (protoreflect.Value, error) {
return d.unmarshalScalar(fd.MapValue()) return d.unmarshalScalar(fd.MapValue())
} }
} }
@ -512,9 +494,9 @@ func (d decoder) unmarshalMap(fd pref.FieldDescriptor, mmap pref.Map) error {
// unmarshalMap unmarshals into given protoreflect.Map. A map value is a // unmarshalMap unmarshals into given protoreflect.Map. A map value is a
// textproto message containing {key: <kvalue>, value: <mvalue>}. // textproto message containing {key: <kvalue>, value: <mvalue>}.
func (d decoder) unmarshalMapEntry(fd pref.FieldDescriptor, mmap pref.Map, unmarshalMapValue func() (pref.Value, error)) error { func (d decoder) unmarshalMapEntry(fd protoreflect.FieldDescriptor, mmap protoreflect.Map, unmarshalMapValue func() (protoreflect.Value, error)) error {
var key pref.MapKey var key protoreflect.MapKey
var pval pref.Value var pval protoreflect.Value
Loop: Loop:
for { for {
// Read field name. // Read field name.
@ -538,7 +520,7 @@ Loop:
return d.unexpectedTokenError(tok) return d.unexpectedTokenError(tok)
} }
switch name := pref.Name(tok.IdentName()); name { switch name := protoreflect.Name(tok.IdentName()); name {
case genid.MapEntry_Key_field_name: case genid.MapEntry_Key_field_name:
if !tok.HasSeparator() { if !tok.HasSeparator() {
return d.syntaxError(tok.Pos(), "missing field separator :") return d.syntaxError(tok.Pos(), "missing field separator :")
@ -553,7 +535,7 @@ Loop:
key = val.MapKey() key = val.MapKey()
case genid.MapEntry_Value_field_name: case genid.MapEntry_Value_field_name:
if kind := fd.MapValue().Kind(); (kind != pref.MessageKind) && (kind != pref.GroupKind) { if kind := fd.MapValue().Kind(); (kind != protoreflect.MessageKind) && (kind != protoreflect.GroupKind) {
if !tok.HasSeparator() { if !tok.HasSeparator() {
return d.syntaxError(tok.Pos(), "missing field separator :") return d.syntaxError(tok.Pos(), "missing field separator :")
} }
@ -579,7 +561,7 @@ Loop:
} }
if !pval.IsValid() { if !pval.IsValid() {
switch fd.MapValue().Kind() { switch fd.MapValue().Kind() {
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
// If value field is not set for message/group types, construct an // If value field is not set for message/group types, construct an
// empty one as default. // empty one as default.
pval = mmap.NewValue() pval = mmap.NewValue()
@ -593,7 +575,7 @@ Loop:
// unmarshalAny unmarshals an Any textproto. It can either be in expanded form // unmarshalAny unmarshals an Any textproto. It can either be in expanded form
// or non-expanded form. // or non-expanded form.
func (d decoder) unmarshalAny(m pref.Message, checkDelims bool) error { func (d decoder) unmarshalAny(m protoreflect.Message, checkDelims bool) error {
var typeURL string var typeURL string
var bValue []byte var bValue []byte
var seenTypeUrl bool var seenTypeUrl bool
@ -637,7 +619,7 @@ Loop:
return d.syntaxError(tok.Pos(), "missing field separator :") return d.syntaxError(tok.Pos(), "missing field separator :")
} }
switch name := pref.Name(tok.IdentName()); name { switch name := protoreflect.Name(tok.IdentName()); name {
case genid.Any_TypeUrl_field_name: case genid.Any_TypeUrl_field_name:
if seenTypeUrl { if seenTypeUrl {
return d.newError(tok.Pos(), "duplicate %v field", genid.Any_TypeUrl_field_fullname) return d.newError(tok.Pos(), "duplicate %v field", genid.Any_TypeUrl_field_fullname)
@ -704,10 +686,10 @@ Loop:
fds := m.Descriptor().Fields() fds := m.Descriptor().Fields()
if len(typeURL) > 0 { if len(typeURL) > 0 {
m.Set(fds.ByNumber(genid.Any_TypeUrl_field_number), pref.ValueOfString(typeURL)) m.Set(fds.ByNumber(genid.Any_TypeUrl_field_number), protoreflect.ValueOfString(typeURL))
} }
if len(bValue) > 0 { if len(bValue) > 0 {
m.Set(fds.ByNumber(genid.Any_Value_field_number), pref.ValueOfBytes(bValue)) m.Set(fds.ByNumber(genid.Any_Value_field_number), protoreflect.ValueOfBytes(bValue))
} }
return nil return nil
} }
@ -762,9 +744,6 @@ func (d decoder) skipValue() error {
// Skip items. This will not validate whether skipped values are // Skip items. This will not validate whether skipped values are
// of the same type or not, same behavior as C++ // of the same type or not, same behavior as C++
// TextFormat::Parser::AllowUnknownField(true) version 3.8.0. // TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
if err := d.skipValue(); err != nil {
return err
}
} }
} }
} }

View File

@ -6,7 +6,6 @@ package prototext
import ( import (
"fmt" "fmt"
"sort"
"strconv" "strconv"
"unicode/utf8" "unicode/utf8"
@ -16,11 +15,11 @@ import (
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/mapsort" "google.golang.org/protobuf/internal/order"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
@ -150,7 +149,7 @@ type encoder struct {
} }
// marshalMessage marshals the given protoreflect.Message. // marshalMessage marshals the given protoreflect.Message.
func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error { func (e encoder) marshalMessage(m protoreflect.Message, inclDelims bool) error {
messageDesc := m.Descriptor() messageDesc := m.Descriptor()
if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
return errors.New("no support for proto1 MessageSets") return errors.New("no support for proto1 MessageSets")
@ -169,35 +168,15 @@ func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error {
// If unable to expand, continue on to marshal Any as a regular message. // If unable to expand, continue on to marshal Any as a regular message.
} }
// Marshal known fields. // Marshal fields.
fieldDescs := messageDesc.Fields() var err error
size := fieldDescs.Len() order.RangeFields(m, order.IndexNameFieldOrder, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
for i := 0; i < size; { if err = e.marshalField(fd.TextName(), v, fd); err != nil {
fd := fieldDescs.Get(i) return false
if od := fd.ContainingOneof(); od != nil {
fd = m.WhichOneof(od)
i += od.Fields().Len()
} else {
i++
} }
return true
if fd == nil || !m.Has(fd) { })
continue if err != nil {
}
name := fd.Name()
// Use type name for group field name.
if fd.Kind() == pref.GroupKind {
name = fd.Message().Name()
}
val := m.Get(fd)
if err := e.marshalField(string(name), val, fd); err != nil {
return err
}
}
// Marshal extensions.
if err := e.marshalExtensions(m); err != nil {
return err return err
} }
@ -210,7 +189,7 @@ func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error {
} }
// marshalField marshals the given field with protoreflect.Value. // marshalField marshals the given field with protoreflect.Value.
func (e encoder) marshalField(name string, val pref.Value, fd pref.FieldDescriptor) error { func (e encoder) marshalField(name string, val protoreflect.Value, fd protoreflect.FieldDescriptor) error {
switch { switch {
case fd.IsList(): case fd.IsList():
return e.marshalList(name, val.List(), fd) return e.marshalList(name, val.List(), fd)
@ -224,40 +203,40 @@ func (e encoder) marshalField(name string, val pref.Value, fd pref.FieldDescript
// marshalSingular marshals the given non-repeated field value. This includes // marshalSingular marshals the given non-repeated field value. This includes
// all scalar types, enums, messages, and groups. // all scalar types, enums, messages, and groups.
func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error { func (e encoder) marshalSingular(val protoreflect.Value, fd protoreflect.FieldDescriptor) error {
kind := fd.Kind() kind := fd.Kind()
switch kind { switch kind {
case pref.BoolKind: case protoreflect.BoolKind:
e.WriteBool(val.Bool()) e.WriteBool(val.Bool())
case pref.StringKind: case protoreflect.StringKind:
s := val.String() s := val.String()
if !e.opts.allowInvalidUTF8 && strs.EnforceUTF8(fd) && !utf8.ValidString(s) { if !e.opts.allowInvalidUTF8 && strs.EnforceUTF8(fd) && !utf8.ValidString(s) {
return errors.InvalidUTF8(string(fd.FullName())) return errors.InvalidUTF8(string(fd.FullName()))
} }
e.WriteString(s) e.WriteString(s)
case pref.Int32Kind, pref.Int64Kind, case protoreflect.Int32Kind, protoreflect.Int64Kind,
pref.Sint32Kind, pref.Sint64Kind, protoreflect.Sint32Kind, protoreflect.Sint64Kind,
pref.Sfixed32Kind, pref.Sfixed64Kind: protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind:
e.WriteInt(val.Int()) e.WriteInt(val.Int())
case pref.Uint32Kind, pref.Uint64Kind, case protoreflect.Uint32Kind, protoreflect.Uint64Kind,
pref.Fixed32Kind, pref.Fixed64Kind: protoreflect.Fixed32Kind, protoreflect.Fixed64Kind:
e.WriteUint(val.Uint()) e.WriteUint(val.Uint())
case pref.FloatKind: case protoreflect.FloatKind:
// Encoder.WriteFloat handles the special numbers NaN and infinites. // Encoder.WriteFloat handles the special numbers NaN and infinites.
e.WriteFloat(val.Float(), 32) e.WriteFloat(val.Float(), 32)
case pref.DoubleKind: case protoreflect.DoubleKind:
// Encoder.WriteFloat handles the special numbers NaN and infinites. // Encoder.WriteFloat handles the special numbers NaN and infinites.
e.WriteFloat(val.Float(), 64) e.WriteFloat(val.Float(), 64)
case pref.BytesKind: case protoreflect.BytesKind:
e.WriteString(string(val.Bytes())) e.WriteString(string(val.Bytes()))
case pref.EnumKind: case protoreflect.EnumKind:
num := val.Enum() num := val.Enum()
if desc := fd.Enum().Values().ByNumber(num); desc != nil { if desc := fd.Enum().Values().ByNumber(num); desc != nil {
e.WriteLiteral(string(desc.Name())) e.WriteLiteral(string(desc.Name()))
@ -266,7 +245,7 @@ func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error
e.WriteInt(int64(num)) e.WriteInt(int64(num))
} }
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
return e.marshalMessage(val.Message(), true) return e.marshalMessage(val.Message(), true)
default: default:
@ -276,7 +255,7 @@ func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error
} }
// marshalList marshals the given protoreflect.List as multiple name-value fields. // marshalList marshals the given protoreflect.List as multiple name-value fields.
func (e encoder) marshalList(name string, list pref.List, fd pref.FieldDescriptor) error { func (e encoder) marshalList(name string, list protoreflect.List, fd protoreflect.FieldDescriptor) error {
size := list.Len() size := list.Len()
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
e.WriteName(name) e.WriteName(name)
@ -288,9 +267,9 @@ func (e encoder) marshalList(name string, list pref.List, fd pref.FieldDescripto
} }
// marshalMap marshals the given protoreflect.Map as multiple name-value fields. // marshalMap marshals the given protoreflect.Map as multiple name-value fields.
func (e encoder) marshalMap(name string, mmap pref.Map, fd pref.FieldDescriptor) error { func (e encoder) marshalMap(name string, mmap protoreflect.Map, fd protoreflect.FieldDescriptor) error {
var err error var err error
mapsort.Range(mmap, fd.MapKey().Kind(), func(key pref.MapKey, val pref.Value) bool { order.RangeEntries(mmap, order.GenericKeyOrder, func(key protoreflect.MapKey, val protoreflect.Value) bool {
e.WriteName(name) e.WriteName(name)
e.StartMessage() e.StartMessage()
defer e.EndMessage() defer e.EndMessage()
@ -311,48 +290,6 @@ func (e encoder) marshalMap(name string, mmap pref.Map, fd pref.FieldDescriptor)
return err return err
} }
// marshalExtensions marshals extension fields.
func (e encoder) marshalExtensions(m pref.Message) error {
type entry struct {
key string
value pref.Value
desc pref.FieldDescriptor
}
// Get a sorted list based on field key first.
var entries []entry
m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
if !fd.IsExtension() {
return true
}
// For MessageSet extensions, the name used is the parent message.
name := fd.FullName()
if messageset.IsMessageSetExtension(fd) {
name = name.Parent()
}
entries = append(entries, entry{
key: string(name),
value: v,
desc: fd,
})
return true
})
// Sort extensions lexicographically.
sort.Slice(entries, func(i, j int) bool {
return entries[i].key < entries[j].key
})
// Write out sorted list.
for _, entry := range entries {
// Extension field name is the proto field name enclosed in [].
name := "[" + entry.key + "]"
if err := e.marshalField(name, entry.value, entry.desc); err != nil {
return err
}
}
return nil
}
// marshalUnknown parses the given []byte and marshals fields out. // marshalUnknown parses the given []byte and marshals fields out.
// This function assumes proper encoding in the given []byte. // This function assumes proper encoding in the given []byte.
func (e encoder) marshalUnknown(b []byte) { func (e encoder) marshalUnknown(b []byte) {
@ -396,7 +333,7 @@ func (e encoder) marshalUnknown(b []byte) {
// marshalAny marshals the given google.protobuf.Any message in expanded form. // marshalAny marshals the given google.protobuf.Any message in expanded form.
// It returns true if it was able to marshal, else false. // It returns true if it was able to marshal, else false.
func (e encoder) marshalAny(any pref.Message) bool { func (e encoder) marshalAny(any protoreflect.Message) bool {
// Construct the embedded message. // Construct the embedded message.
fds := any.Descriptor().Fields() fds := any.Descriptor().Fields()
fdType := fds.ByNumber(genid.Any_TypeUrl_field_number) fdType := fds.ByNumber(genid.Any_TypeUrl_field_number)

View File

@ -25,6 +25,7 @@ const (
FirstReservedNumber Number = 19000 FirstReservedNumber Number = 19000
LastReservedNumber Number = 19999 LastReservedNumber Number = 19999
MaxValidNumber Number = 1<<29 - 1 MaxValidNumber Number = 1<<29 - 1
DefaultRecursionLimit = 10000
) )
// IsValid reports whether the field number is semantically valid. // IsValid reports whether the field number is semantically valid.
@ -55,6 +56,7 @@ const (
errCodeOverflow errCodeOverflow
errCodeReserved errCodeReserved
errCodeEndGroup errCodeEndGroup
errCodeRecursionDepth
) )
var ( var (
@ -112,6 +114,10 @@ func ConsumeField(b []byte) (Number, Type, int) {
// When parsing a group, the length includes the end group marker and // When parsing a group, the length includes the end group marker and
// the end group is verified to match the starting field number. // the end group is verified to match the starting field number.
func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) { func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
return consumeFieldValueD(num, typ, b, DefaultRecursionLimit)
}
func consumeFieldValueD(num Number, typ Type, b []byte, depth int) (n int) {
switch typ { switch typ {
case VarintType: case VarintType:
_, n = ConsumeVarint(b) _, n = ConsumeVarint(b)
@ -126,6 +132,9 @@ func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
_, n = ConsumeBytes(b) _, n = ConsumeBytes(b)
return n return n
case StartGroupType: case StartGroupType:
if depth < 0 {
return errCodeRecursionDepth
}
n0 := len(b) n0 := len(b)
for { for {
num2, typ2, n := ConsumeTag(b) num2, typ2, n := ConsumeTag(b)
@ -140,7 +149,7 @@ func ConsumeFieldValue(num Number, typ Type, b []byte) (n int) {
return n0 - len(b) return n0 - len(b)
} }
n = ConsumeFieldValue(num2, typ2, b) n = consumeFieldValueD(num2, typ2, b, depth-1)
if n < 0 { if n < 0 {
return n // forward error code return n // forward error code
} }
@ -507,6 +516,7 @@ func EncodeTag(num Number, typ Type) uint64 {
} }
// DecodeZigZag decodes a zig-zag-encoded uint64 as an int64. // DecodeZigZag decodes a zig-zag-encoded uint64 as an int64.
//
// Input: {…, 5, 3, 1, 0, 2, 4, 6, …} // Input: {…, 5, 3, 1, 0, 2, 4, 6, …}
// Output: {…, -3, -2, -1, 0, +1, +2, +3, …} // Output: {…, -3, -2, -1, 0, +1, +2, +3, …}
func DecodeZigZag(x uint64) int64 { func DecodeZigZag(x uint64) int64 {
@ -514,6 +524,7 @@ func DecodeZigZag(x uint64) int64 {
} }
// EncodeZigZag encodes an int64 as a zig-zag-encoded uint64. // EncodeZigZag encodes an int64 as a zig-zag-encoded uint64.
//
// Input: {…, -3, -2, -1, 0, +1, +2, +3, …} // Input: {…, -3, -2, -1, 0, +1, +2, +3, …}
// Output: {…, 5, 3, 1, 0, 2, 4, 6, …} // Output: {…, 5, 3, 1, 0, 2, 4, 6, …}
func EncodeZigZag(x int64) uint64 { func EncodeZigZag(x int64) uint64 {
@ -521,6 +532,7 @@ func EncodeZigZag(x int64) uint64 {
} }
// DecodeBool decodes a uint64 as a bool. // DecodeBool decodes a uint64 as a bool.
//
// Input: { 0, 1, 2, …} // Input: { 0, 1, 2, …}
// Output: {false, true, true, …} // Output: {false, true, true, …}
func DecodeBool(x uint64) bool { func DecodeBool(x uint64) bool {
@ -528,6 +540,7 @@ func DecodeBool(x uint64) bool {
} }
// EncodeBool encodes a bool as a uint64. // EncodeBool encodes a bool as a uint64.
//
// Input: {false, true} // Input: {false, true}
// Output: { 0, 1} // Output: { 0, 1}
func EncodeBool(x bool) uint64 { func EncodeBool(x bool) uint64 {

View File

@ -14,7 +14,7 @@ import (
"google.golang.org/protobuf/internal/detrand" "google.golang.org/protobuf/internal/detrand"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type list interface { type list interface {
@ -30,35 +30,37 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string {
if isRoot { if isRoot {
var name string var name string
switch vs.(type) { switch vs.(type) {
case pref.Names: case protoreflect.Names:
name = "Names" name = "Names"
case pref.FieldNumbers: case protoreflect.FieldNumbers:
name = "FieldNumbers" name = "FieldNumbers"
case pref.FieldRanges: case protoreflect.FieldRanges:
name = "FieldRanges" name = "FieldRanges"
case pref.EnumRanges: case protoreflect.EnumRanges:
name = "EnumRanges" name = "EnumRanges"
case pref.FileImports: case protoreflect.FileImports:
name = "FileImports" name = "FileImports"
case pref.Descriptor: case protoreflect.Descriptor:
name = reflect.ValueOf(vs).MethodByName("Get").Type().Out(0).Name() + "s" name = reflect.ValueOf(vs).MethodByName("Get").Type().Out(0).Name() + "s"
default:
name = reflect.ValueOf(vs).Elem().Type().Name()
} }
start, end = name+"{", "}" start, end = name+"{", "}"
} }
var ss []string var ss []string
switch vs := vs.(type) { switch vs := vs.(type) {
case pref.Names: case protoreflect.Names:
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
ss = append(ss, fmt.Sprint(vs.Get(i))) ss = append(ss, fmt.Sprint(vs.Get(i)))
} }
return start + joinStrings(ss, false) + end return start + joinStrings(ss, false) + end
case pref.FieldNumbers: case protoreflect.FieldNumbers:
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
ss = append(ss, fmt.Sprint(vs.Get(i))) ss = append(ss, fmt.Sprint(vs.Get(i)))
} }
return start + joinStrings(ss, false) + end return start + joinStrings(ss, false) + end
case pref.FieldRanges: case protoreflect.FieldRanges:
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
r := vs.Get(i) r := vs.Get(i)
if r[0]+1 == r[1] { if r[0]+1 == r[1] {
@ -68,7 +70,7 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string {
} }
} }
return start + joinStrings(ss, false) + end return start + joinStrings(ss, false) + end
case pref.EnumRanges: case protoreflect.EnumRanges:
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
r := vs.Get(i) r := vs.Get(i)
if r[0] == r[1] { if r[0] == r[1] {
@ -78,7 +80,7 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string {
} }
} }
return start + joinStrings(ss, false) + end return start + joinStrings(ss, false) + end
case pref.FileImports: case protoreflect.FileImports:
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
var rs records var rs records
rs.Append(reflect.ValueOf(vs.Get(i)), "Path", "Package", "IsPublic", "IsWeak") rs.Append(reflect.ValueOf(vs.Get(i)), "Path", "Package", "IsPublic", "IsWeak")
@ -86,11 +88,11 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string {
} }
return start + joinStrings(ss, allowMulti) + end return start + joinStrings(ss, allowMulti) + end
default: default:
_, isEnumValue := vs.(pref.EnumValueDescriptors) _, isEnumValue := vs.(protoreflect.EnumValueDescriptors)
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
m := reflect.ValueOf(vs).MethodByName("Get") m := reflect.ValueOf(vs).MethodByName("Get")
v := m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface() v := m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface()
ss = append(ss, formatDescOpt(v.(pref.Descriptor), false, allowMulti && !isEnumValue)) ss = append(ss, formatDescOpt(v.(protoreflect.Descriptor), false, allowMulti && !isEnumValue))
} }
return start + joinStrings(ss, allowMulti && isEnumValue) + end return start + joinStrings(ss, allowMulti && isEnumValue) + end
} }
@ -104,20 +106,20 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string {
// //
// Using a list allows us to print the accessors in a sensible order. // Using a list allows us to print the accessors in a sensible order.
var descriptorAccessors = map[reflect.Type][]string{ var descriptorAccessors = map[reflect.Type][]string{
reflect.TypeOf((*pref.FileDescriptor)(nil)).Elem(): {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"}, reflect.TypeOf((*protoreflect.FileDescriptor)(nil)).Elem(): {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"},
reflect.TypeOf((*pref.MessageDescriptor)(nil)).Elem(): {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"}, reflect.TypeOf((*protoreflect.MessageDescriptor)(nil)).Elem(): {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"},
reflect.TypeOf((*pref.FieldDescriptor)(nil)).Elem(): {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"}, reflect.TypeOf((*protoreflect.FieldDescriptor)(nil)).Elem(): {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"},
reflect.TypeOf((*pref.OneofDescriptor)(nil)).Elem(): {"Fields"}, // not directly used; must keep in sync with formatDescOpt reflect.TypeOf((*protoreflect.OneofDescriptor)(nil)).Elem(): {"Fields"}, // not directly used; must keep in sync with formatDescOpt
reflect.TypeOf((*pref.EnumDescriptor)(nil)).Elem(): {"Values", "ReservedNames", "ReservedRanges"}, reflect.TypeOf((*protoreflect.EnumDescriptor)(nil)).Elem(): {"Values", "ReservedNames", "ReservedRanges"},
reflect.TypeOf((*pref.EnumValueDescriptor)(nil)).Elem(): {"Number"}, reflect.TypeOf((*protoreflect.EnumValueDescriptor)(nil)).Elem(): {"Number"},
reflect.TypeOf((*pref.ServiceDescriptor)(nil)).Elem(): {"Methods"}, reflect.TypeOf((*protoreflect.ServiceDescriptor)(nil)).Elem(): {"Methods"},
reflect.TypeOf((*pref.MethodDescriptor)(nil)).Elem(): {"Input", "Output", "IsStreamingClient", "IsStreamingServer"}, reflect.TypeOf((*protoreflect.MethodDescriptor)(nil)).Elem(): {"Input", "Output", "IsStreamingClient", "IsStreamingServer"},
} }
func FormatDesc(s fmt.State, r rune, t pref.Descriptor) { func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) {
io.WriteString(s, formatDescOpt(t, true, r == 'v' && (s.Flag('+') || s.Flag('#')))) io.WriteString(s, formatDescOpt(t, true, r == 'v' && (s.Flag('+') || s.Flag('#'))))
} }
func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool) string {
rv := reflect.ValueOf(t) rv := reflect.ValueOf(t)
rt := rv.MethodByName("ProtoType").Type().In(0) rt := rv.MethodByName("ProtoType").Type().In(0)
@ -126,7 +128,7 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string {
start = rt.Name() + "{" start = rt.Name() + "{"
} }
_, isFile := t.(pref.FileDescriptor) _, isFile := t.(protoreflect.FileDescriptor)
rs := records{allowMulti: allowMulti} rs := records{allowMulti: allowMulti}
if t.IsPlaceholder() { if t.IsPlaceholder() {
if isFile { if isFile {
@ -144,7 +146,7 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string {
rs.Append(rv, "Name") rs.Append(rv, "Name")
} }
switch t := t.(type) { switch t := t.(type) {
case pref.FieldDescriptor: case protoreflect.FieldDescriptor:
for _, s := range descriptorAccessors[rt] { for _, s := range descriptorAccessors[rt] {
switch s { switch s {
case "MapKey": case "MapKey":
@ -154,9 +156,9 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string {
case "MapValue": case "MapValue":
if v := t.MapValue(); v != nil { if v := t.MapValue(); v != nil {
switch v.Kind() { switch v.Kind() {
case pref.EnumKind: case protoreflect.EnumKind:
rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Enum().FullName())}) rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Enum().FullName())})
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Message().FullName())}) rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Message().FullName())})
default: default:
rs.recs = append(rs.recs, [2]string{"MapValue", v.Kind().String()}) rs.recs = append(rs.recs, [2]string{"MapValue", v.Kind().String()})
@ -178,7 +180,7 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string {
rs.Append(rv, s) rs.Append(rv, s)
} }
} }
case pref.OneofDescriptor: case protoreflect.OneofDescriptor:
var ss []string var ss []string
fs := t.Fields() fs := t.Fields()
for i := 0; i < fs.Len(); i++ { for i := 0; i < fs.Len(); i++ {
@ -214,7 +216,7 @@ func (rs *records) Append(v reflect.Value, accessors ...string) {
if !rv.IsValid() { if !rv.IsValid() {
panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a)) panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a))
} }
if _, ok := rv.Interface().(pref.Value); ok { if _, ok := rv.Interface().(protoreflect.Value); ok {
rv = rv.MethodByName("Interface").Call(nil)[0] rv = rv.MethodByName("Interface").Call(nil)[0]
if !rv.IsNil() { if !rv.IsNil() {
rv = rv.Elem() rv = rv.Elem()
@ -248,9 +250,9 @@ func (rs *records) Append(v reflect.Value, accessors ...string) {
switch v := v.(type) { switch v := v.(type) {
case list: case list:
s = formatListOpt(v, false, rs.allowMulti) s = formatListOpt(v, false, rs.allowMulti)
case pref.FieldDescriptor, pref.OneofDescriptor, pref.EnumValueDescriptor, pref.MethodDescriptor: case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor:
s = string(v.(pref.Descriptor).Name()) s = string(v.(protoreflect.Descriptor).Name())
case pref.Descriptor: case protoreflect.Descriptor:
s = string(v.FullName()) s = string(v.FullName())
case string: case string:
s = strconv.Quote(v) s = strconv.Quote(v)

View File

@ -26,6 +26,14 @@ func Bool() bool {
return randSeed%2 == 1 return randSeed%2 == 1
} }
// Intn returns a deterministically random integer between 0 and n-1, inclusive.
func Intn(n int) int {
if n <= 0 {
panic("must be positive")
}
return int(randSeed % uint64(n))
}
// randSeed is a best-effort at an approximate hash of the Go binary. // randSeed is a best-effort at an approximate hash of the Go binary.
var randSeed = binaryHash() var randSeed = binaryHash()

View File

@ -15,8 +15,8 @@ import (
"strconv" "strconv"
ptext "google.golang.org/protobuf/internal/encoding/text" ptext "google.golang.org/protobuf/internal/encoding/text"
errors "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
// Format is the serialization format used to represent the default value. // Format is the serialization format used to represent the default value.
@ -35,56 +35,56 @@ const (
// Unmarshal deserializes the default string s according to the given kind k. // Unmarshal deserializes the default string s according to the given kind k.
// When k is an enum, a list of enum value descriptors must be provided. // When k is an enum, a list of enum value descriptors must be provided.
func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (pref.Value, pref.EnumValueDescriptor, error) { func Unmarshal(s string, k protoreflect.Kind, evs protoreflect.EnumValueDescriptors, f Format) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) {
switch k { switch k {
case pref.BoolKind: case protoreflect.BoolKind:
if f == GoTag { if f == GoTag {
switch s { switch s {
case "1": case "1":
return pref.ValueOfBool(true), nil, nil return protoreflect.ValueOfBool(true), nil, nil
case "0": case "0":
return pref.ValueOfBool(false), nil, nil return protoreflect.ValueOfBool(false), nil, nil
} }
} else { } else {
switch s { switch s {
case "true": case "true":
return pref.ValueOfBool(true), nil, nil return protoreflect.ValueOfBool(true), nil, nil
case "false": case "false":
return pref.ValueOfBool(false), nil, nil return protoreflect.ValueOfBool(false), nil, nil
} }
} }
case pref.EnumKind: case protoreflect.EnumKind:
if f == GoTag { if f == GoTag {
// Go tags use the numeric form of the enum value. // Go tags use the numeric form of the enum value.
if n, err := strconv.ParseInt(s, 10, 32); err == nil { if n, err := strconv.ParseInt(s, 10, 32); err == nil {
if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil { if ev := evs.ByNumber(protoreflect.EnumNumber(n)); ev != nil {
return pref.ValueOfEnum(ev.Number()), ev, nil return protoreflect.ValueOfEnum(ev.Number()), ev, nil
} }
} }
} else { } else {
// Descriptor default_value use the enum identifier. // Descriptor default_value use the enum identifier.
ev := evs.ByName(pref.Name(s)) ev := evs.ByName(protoreflect.Name(s))
if ev != nil { if ev != nil {
return pref.ValueOfEnum(ev.Number()), ev, nil return protoreflect.ValueOfEnum(ev.Number()), ev, nil
} }
} }
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
if v, err := strconv.ParseInt(s, 10, 32); err == nil { if v, err := strconv.ParseInt(s, 10, 32); err == nil {
return pref.ValueOfInt32(int32(v)), nil, nil return protoreflect.ValueOfInt32(int32(v)), nil, nil
} }
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
if v, err := strconv.ParseInt(s, 10, 64); err == nil { if v, err := strconv.ParseInt(s, 10, 64); err == nil {
return pref.ValueOfInt64(int64(v)), nil, nil return protoreflect.ValueOfInt64(int64(v)), nil, nil
} }
case pref.Uint32Kind, pref.Fixed32Kind: case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
if v, err := strconv.ParseUint(s, 10, 32); err == nil { if v, err := strconv.ParseUint(s, 10, 32); err == nil {
return pref.ValueOfUint32(uint32(v)), nil, nil return protoreflect.ValueOfUint32(uint32(v)), nil, nil
} }
case pref.Uint64Kind, pref.Fixed64Kind: case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
if v, err := strconv.ParseUint(s, 10, 64); err == nil { if v, err := strconv.ParseUint(s, 10, 64); err == nil {
return pref.ValueOfUint64(uint64(v)), nil, nil return protoreflect.ValueOfUint64(uint64(v)), nil, nil
} }
case pref.FloatKind, pref.DoubleKind: case protoreflect.FloatKind, protoreflect.DoubleKind:
var v float64 var v float64
var err error var err error
switch s { switch s {
@ -98,29 +98,29 @@ func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (
v, err = strconv.ParseFloat(s, 64) v, err = strconv.ParseFloat(s, 64)
} }
if err == nil { if err == nil {
if k == pref.FloatKind { if k == protoreflect.FloatKind {
return pref.ValueOfFloat32(float32(v)), nil, nil return protoreflect.ValueOfFloat32(float32(v)), nil, nil
} else { } else {
return pref.ValueOfFloat64(float64(v)), nil, nil return protoreflect.ValueOfFloat64(float64(v)), nil, nil
} }
} }
case pref.StringKind: case protoreflect.StringKind:
// String values are already unescaped and can be used as is. // String values are already unescaped and can be used as is.
return pref.ValueOfString(s), nil, nil return protoreflect.ValueOfString(s), nil, nil
case pref.BytesKind: case protoreflect.BytesKind:
if b, ok := unmarshalBytes(s); ok { if b, ok := unmarshalBytes(s); ok {
return pref.ValueOfBytes(b), nil, nil return protoreflect.ValueOfBytes(b), nil, nil
} }
} }
return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s) return protoreflect.Value{}, nil, errors.New("could not parse value for %v: %q", k, s)
} }
// Marshal serializes v as the default string according to the given kind k. // Marshal serializes v as the default string according to the given kind k.
// When specifying the Descriptor format for an enum kind, the associated // When specifying the Descriptor format for an enum kind, the associated
// enum value descriptor must be provided. // enum value descriptor must be provided.
func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (string, error) { func Marshal(v protoreflect.Value, ev protoreflect.EnumValueDescriptor, k protoreflect.Kind, f Format) (string, error) {
switch k { switch k {
case pref.BoolKind: case protoreflect.BoolKind:
if f == GoTag { if f == GoTag {
if v.Bool() { if v.Bool() {
return "1", nil return "1", nil
@ -134,17 +134,17 @@ func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (
return "false", nil return "false", nil
} }
} }
case pref.EnumKind: case protoreflect.EnumKind:
if f == GoTag { if f == GoTag {
return strconv.FormatInt(int64(v.Enum()), 10), nil return strconv.FormatInt(int64(v.Enum()), 10), nil
} else { } else {
return string(ev.Name()), nil return string(ev.Name()), nil
} }
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
return strconv.FormatInt(v.Int(), 10), nil return strconv.FormatInt(v.Int(), 10), nil
case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind: case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
return strconv.FormatUint(v.Uint(), 10), nil return strconv.FormatUint(v.Uint(), 10), nil
case pref.FloatKind, pref.DoubleKind: case protoreflect.FloatKind, protoreflect.DoubleKind:
f := v.Float() f := v.Float()
switch { switch {
case math.IsInf(f, -1): case math.IsInf(f, -1):
@ -154,16 +154,16 @@ func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (
case math.IsNaN(f): case math.IsNaN(f):
return "nan", nil return "nan", nil
default: default:
if k == pref.FloatKind { if k == protoreflect.FloatKind {
return strconv.FormatFloat(f, 'g', -1, 32), nil return strconv.FormatFloat(f, 'g', -1, 32), nil
} else { } else {
return strconv.FormatFloat(f, 'g', -1, 64), nil return strconv.FormatFloat(f, 'g', -1, 64), nil
} }
} }
case pref.StringKind: case protoreflect.StringKind:
// String values are serialized as is without any escaping. // String values are serialized as is without any escaping.
return v.String(), nil return v.String(), nil
case pref.BytesKind: case protoreflect.BytesKind:
if s, ok := marshalBytes(v.Bytes()); ok { if s, ok := marshalBytes(v.Bytes()); ok {
return s, nil return s, nil
} }

View File

@ -10,11 +10,10 @@ import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry"
) )
// The MessageSet wire format is equivalent to a message defiend as follows, // The MessageSet wire format is equivalent to a message defined as follows,
// where each Item defines an extension field with a field number of 'type_id' // where each Item defines an extension field with a field number of 'type_id'
// and content of 'message'. MessageSet extensions must be non-repeated message // and content of 'message'. MessageSet extensions must be non-repeated message
// fields. // fields.
@ -34,6 +33,7 @@ const (
// ExtensionName is the field name for extensions of MessageSet. // ExtensionName is the field name for extensions of MessageSet.
// //
// A valid MessageSet extension must be of the form: // A valid MessageSet extension must be of the form:
//
// message MyMessage { // message MyMessage {
// extend proto2.bridge.MessageSet { // extend proto2.bridge.MessageSet {
// optional MyMessage message_set_extension = 1234; // optional MyMessage message_set_extension = 1234;
@ -43,38 +43,22 @@ const (
const ExtensionName = "message_set_extension" const ExtensionName = "message_set_extension"
// IsMessageSet returns whether the message uses the MessageSet wire format. // IsMessageSet returns whether the message uses the MessageSet wire format.
func IsMessageSet(md pref.MessageDescriptor) bool { func IsMessageSet(md protoreflect.MessageDescriptor) bool {
xmd, ok := md.(interface{ IsMessageSet() bool }) xmd, ok := md.(interface{ IsMessageSet() bool })
return ok && xmd.IsMessageSet() return ok && xmd.IsMessageSet()
} }
// IsMessageSetExtension reports this field extends a MessageSet. // IsMessageSetExtension reports this field properly extends a MessageSet.
func IsMessageSetExtension(fd pref.FieldDescriptor) bool { func IsMessageSetExtension(fd protoreflect.FieldDescriptor) bool {
if fd.Name() != ExtensionName { switch {
case fd.Name() != ExtensionName:
return false
case !IsMessageSet(fd.ContainingMessage()):
return false
case fd.FullName().Parent() != fd.Message().FullName():
return false return false
} }
if fd.FullName().Parent() != fd.Message().FullName() { return true
return false
}
return IsMessageSet(fd.ContainingMessage())
}
// FindMessageSetExtension locates a MessageSet extension field by name.
// In text and JSON formats, the extension name used is the message itself.
// The extension field name is derived by appending ExtensionName.
func FindMessageSetExtension(r preg.ExtensionTypeResolver, s pref.FullName) (pref.ExtensionType, error) {
name := s.Append(ExtensionName)
xt, err := r.FindExtensionByName(name)
if err != nil {
if err == preg.NotFound {
return nil, err
}
return nil, errors.Wrap(err, "%q", name)
}
if !IsMessageSetExtension(xt.TypeDescriptor()) {
return nil, preg.NotFound
}
return xt, nil
} }
// SizeField returns the size of a MessageSet item field containing an extension // SizeField returns the size of a MessageSet item field containing an extension

View File

@ -11,10 +11,10 @@ import (
"strconv" "strconv"
"strings" "strings"
defval "google.golang.org/protobuf/internal/encoding/defval" "google.golang.org/protobuf/internal/encoding/defval"
fdesc "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
var byteType = reflect.TypeOf(byte(0)) var byteType = reflect.TypeOf(byte(0))
@ -29,9 +29,9 @@ var byteType = reflect.TypeOf(byte(0))
// This does not populate the Enum or Message (except for weak message). // This does not populate the Enum or Message (except for weak message).
// //
// This function is a best effort attempt; parsing errors are ignored. // This function is a best effort attempt; parsing errors are ignored.
func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) pref.FieldDescriptor { func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor {
f := new(fdesc.Field) f := new(filedesc.Field)
f.L0.ParentFile = fdesc.SurrogateProto2 f.L0.ParentFile = filedesc.SurrogateProto2
for len(tag) > 0 { for len(tag) > 0 {
i := strings.IndexByte(tag, ',') i := strings.IndexByte(tag, ',')
if i < 0 { if i < 0 {
@ -39,95 +39,95 @@ func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) p
} }
switch s := tag[:i]; { switch s := tag[:i]; {
case strings.HasPrefix(s, "name="): case strings.HasPrefix(s, "name="):
f.L0.FullName = pref.FullName(s[len("name="):]) f.L0.FullName = protoreflect.FullName(s[len("name="):])
case strings.Trim(s, "0123456789") == "": case strings.Trim(s, "0123456789") == "":
n, _ := strconv.ParseUint(s, 10, 32) n, _ := strconv.ParseUint(s, 10, 32)
f.L1.Number = pref.FieldNumber(n) f.L1.Number = protoreflect.FieldNumber(n)
case s == "opt": case s == "opt":
f.L1.Cardinality = pref.Optional f.L1.Cardinality = protoreflect.Optional
case s == "req": case s == "req":
f.L1.Cardinality = pref.Required f.L1.Cardinality = protoreflect.Required
case s == "rep": case s == "rep":
f.L1.Cardinality = pref.Repeated f.L1.Cardinality = protoreflect.Repeated
case s == "varint": case s == "varint":
switch goType.Kind() { switch goType.Kind() {
case reflect.Bool: case reflect.Bool:
f.L1.Kind = pref.BoolKind f.L1.Kind = protoreflect.BoolKind
case reflect.Int32: case reflect.Int32:
f.L1.Kind = pref.Int32Kind f.L1.Kind = protoreflect.Int32Kind
case reflect.Int64: case reflect.Int64:
f.L1.Kind = pref.Int64Kind f.L1.Kind = protoreflect.Int64Kind
case reflect.Uint32: case reflect.Uint32:
f.L1.Kind = pref.Uint32Kind f.L1.Kind = protoreflect.Uint32Kind
case reflect.Uint64: case reflect.Uint64:
f.L1.Kind = pref.Uint64Kind f.L1.Kind = protoreflect.Uint64Kind
} }
case s == "zigzag32": case s == "zigzag32":
if goType.Kind() == reflect.Int32 { if goType.Kind() == reflect.Int32 {
f.L1.Kind = pref.Sint32Kind f.L1.Kind = protoreflect.Sint32Kind
} }
case s == "zigzag64": case s == "zigzag64":
if goType.Kind() == reflect.Int64 { if goType.Kind() == reflect.Int64 {
f.L1.Kind = pref.Sint64Kind f.L1.Kind = protoreflect.Sint64Kind
} }
case s == "fixed32": case s == "fixed32":
switch goType.Kind() { switch goType.Kind() {
case reflect.Int32: case reflect.Int32:
f.L1.Kind = pref.Sfixed32Kind f.L1.Kind = protoreflect.Sfixed32Kind
case reflect.Uint32: case reflect.Uint32:
f.L1.Kind = pref.Fixed32Kind f.L1.Kind = protoreflect.Fixed32Kind
case reflect.Float32: case reflect.Float32:
f.L1.Kind = pref.FloatKind f.L1.Kind = protoreflect.FloatKind
} }
case s == "fixed64": case s == "fixed64":
switch goType.Kind() { switch goType.Kind() {
case reflect.Int64: case reflect.Int64:
f.L1.Kind = pref.Sfixed64Kind f.L1.Kind = protoreflect.Sfixed64Kind
case reflect.Uint64: case reflect.Uint64:
f.L1.Kind = pref.Fixed64Kind f.L1.Kind = protoreflect.Fixed64Kind
case reflect.Float64: case reflect.Float64:
f.L1.Kind = pref.DoubleKind f.L1.Kind = protoreflect.DoubleKind
} }
case s == "bytes": case s == "bytes":
switch { switch {
case goType.Kind() == reflect.String: case goType.Kind() == reflect.String:
f.L1.Kind = pref.StringKind f.L1.Kind = protoreflect.StringKind
case goType.Kind() == reflect.Slice && goType.Elem() == byteType: case goType.Kind() == reflect.Slice && goType.Elem() == byteType:
f.L1.Kind = pref.BytesKind f.L1.Kind = protoreflect.BytesKind
default: default:
f.L1.Kind = pref.MessageKind f.L1.Kind = protoreflect.MessageKind
} }
case s == "group": case s == "group":
f.L1.Kind = pref.GroupKind f.L1.Kind = protoreflect.GroupKind
case strings.HasPrefix(s, "enum="): case strings.HasPrefix(s, "enum="):
f.L1.Kind = pref.EnumKind f.L1.Kind = protoreflect.EnumKind
case strings.HasPrefix(s, "json="): case strings.HasPrefix(s, "json="):
jsonName := s[len("json="):] jsonName := s[len("json="):]
if jsonName != strs.JSONCamelCase(string(f.L0.FullName.Name())) { if jsonName != strs.JSONCamelCase(string(f.L0.FullName.Name())) {
f.L1.JSONName.Init(jsonName) f.L1.StringName.InitJSON(jsonName)
} }
case s == "packed": case s == "packed":
f.L1.HasPacked = true f.L1.HasPacked = true
f.L1.IsPacked = true f.L1.IsPacked = true
case strings.HasPrefix(s, "weak="): case strings.HasPrefix(s, "weak="):
f.L1.IsWeak = true f.L1.IsWeak = true
f.L1.Message = fdesc.PlaceholderMessage(pref.FullName(s[len("weak="):])) f.L1.Message = filedesc.PlaceholderMessage(protoreflect.FullName(s[len("weak="):]))
case strings.HasPrefix(s, "def="): case strings.HasPrefix(s, "def="):
// The default tag is special in that everything afterwards is the // The default tag is special in that everything afterwards is the
// default regardless of the presence of commas. // default regardless of the presence of commas.
s, i = tag[len("def="):], len(tag) s, i = tag[len("def="):], len(tag)
v, ev, _ := defval.Unmarshal(s, f.L1.Kind, evs, defval.GoTag) v, ev, _ := defval.Unmarshal(s, f.L1.Kind, evs, defval.GoTag)
f.L1.Default = fdesc.DefaultValue(v, ev) f.L1.Default = filedesc.DefaultValue(v, ev)
case s == "proto3": case s == "proto3":
f.L0.ParentFile = fdesc.SurrogateProto3 f.L0.ParentFile = filedesc.SurrogateProto3
} }
tag = strings.TrimPrefix(tag[i:], ",") tag = strings.TrimPrefix(tag[i:], ",")
} }
// The generator uses the group message name instead of the field name. // The generator uses the group message name instead of the field name.
// We obtain the real field name by lowercasing the group name. // We obtain the real field name by lowercasing the group name.
if f.L1.Kind == pref.GroupKind { if f.L1.Kind == protoreflect.GroupKind {
f.L0.FullName = pref.FullName(strings.ToLower(string(f.L0.FullName))) f.L0.FullName = protoreflect.FullName(strings.ToLower(string(f.L0.FullName)))
} }
return f return f
} }
@ -140,38 +140,38 @@ func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) p
// Depending on the context on how Marshal is called, there are different ways // Depending on the context on how Marshal is called, there are different ways
// through which that information is determined. As such it is the caller's // through which that information is determined. As such it is the caller's
// responsibility to provide a function to obtain that information. // responsibility to provide a function to obtain that information.
func Marshal(fd pref.FieldDescriptor, enumName string) string { func Marshal(fd protoreflect.FieldDescriptor, enumName string) string {
var tag []string var tag []string
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind, pref.EnumKind, pref.Int32Kind, pref.Uint32Kind, pref.Int64Kind, pref.Uint64Kind: case protoreflect.BoolKind, protoreflect.EnumKind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Int64Kind, protoreflect.Uint64Kind:
tag = append(tag, "varint") tag = append(tag, "varint")
case pref.Sint32Kind: case protoreflect.Sint32Kind:
tag = append(tag, "zigzag32") tag = append(tag, "zigzag32")
case pref.Sint64Kind: case protoreflect.Sint64Kind:
tag = append(tag, "zigzag64") tag = append(tag, "zigzag64")
case pref.Sfixed32Kind, pref.Fixed32Kind, pref.FloatKind: case protoreflect.Sfixed32Kind, protoreflect.Fixed32Kind, protoreflect.FloatKind:
tag = append(tag, "fixed32") tag = append(tag, "fixed32")
case pref.Sfixed64Kind, pref.Fixed64Kind, pref.DoubleKind: case protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind, protoreflect.DoubleKind:
tag = append(tag, "fixed64") tag = append(tag, "fixed64")
case pref.StringKind, pref.BytesKind, pref.MessageKind: case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind:
tag = append(tag, "bytes") tag = append(tag, "bytes")
case pref.GroupKind: case protoreflect.GroupKind:
tag = append(tag, "group") tag = append(tag, "group")
} }
tag = append(tag, strconv.Itoa(int(fd.Number()))) tag = append(tag, strconv.Itoa(int(fd.Number())))
switch fd.Cardinality() { switch fd.Cardinality() {
case pref.Optional: case protoreflect.Optional:
tag = append(tag, "opt") tag = append(tag, "opt")
case pref.Required: case protoreflect.Required:
tag = append(tag, "req") tag = append(tag, "req")
case pref.Repeated: case protoreflect.Repeated:
tag = append(tag, "rep") tag = append(tag, "rep")
} }
if fd.IsPacked() { if fd.IsPacked() {
tag = append(tag, "packed") tag = append(tag, "packed")
} }
name := string(fd.Name()) name := string(fd.Name())
if fd.Kind() == pref.GroupKind { if fd.Kind() == protoreflect.GroupKind {
// The name of the FieldDescriptor for a group field is // The name of the FieldDescriptor for a group field is
// lowercased. To find the original capitalization, we // lowercased. To find the original capitalization, we
// look in the field's MessageType. // look in the field's MessageType.
@ -189,10 +189,10 @@ func Marshal(fd pref.FieldDescriptor, enumName string) string {
// The previous implementation does not tag extension fields as proto3, // The previous implementation does not tag extension fields as proto3,
// even when the field is defined in a proto3 file. Match that behavior // even when the field is defined in a proto3 file. Match that behavior
// for consistency. // for consistency.
if fd.Syntax() == pref.Proto3 && !fd.IsExtension() { if fd.Syntax() == protoreflect.Proto3 && !fd.IsExtension() {
tag = append(tag, "proto3") tag = append(tag, "proto3")
} }
if fd.Kind() == pref.EnumKind && enumName != "" { if fd.Kind() == protoreflect.EnumKind && enumName != "" {
tag = append(tag, "enum="+enumName) tag = append(tag, "enum="+enumName)
} }
if fd.ContainingOneof() != nil { if fd.ContainingOneof() != nil {

View File

@ -8,7 +8,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"regexp"
"strconv" "strconv"
"unicode/utf8" "unicode/utf8"
@ -381,7 +380,7 @@ func (d *Decoder) currentOpenKind() (Kind, byte) {
case '[': case '[':
return ListOpen, ']' return ListOpen, ']'
} }
panic(fmt.Sprintf("Decoder: openStack contains invalid byte %s", string(openCh))) panic(fmt.Sprintf("Decoder: openStack contains invalid byte %c", openCh))
} }
func (d *Decoder) pushOpenStack(ch byte) { func (d *Decoder) pushOpenStack(ch byte) {
@ -421,7 +420,7 @@ func (d *Decoder) parseFieldName() (tok Token, err error) {
return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size]) return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size])
} }
return Token{}, d.newSyntaxError("invalid field name: %s", errRegexp.Find(d.in)) return Token{}, d.newSyntaxError("invalid field name: %s", errId(d.in))
} }
// parseTypeName parses Any type URL or extension field name. The name is // parseTypeName parses Any type URL or extension field name. The name is
@ -571,7 +570,7 @@ func (d *Decoder) parseScalar() (Token, error) {
return tok, nil return tok, nil
} }
return Token{}, d.newSyntaxError("invalid scalar value: %s", errRegexp.Find(d.in)) return Token{}, d.newSyntaxError("invalid scalar value: %s", errId(d.in))
} }
// parseLiteralValue parses a literal value. A literal value is used for // parseLiteralValue parses a literal value. A literal value is used for
@ -653,8 +652,29 @@ func consume(b []byte, n int) []byte {
return b return b
} }
// Any sequence that looks like a non-delimiter (for error reporting). // errId extracts a byte sequence that looks like an invalid ID
var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9\/]+|.)`) // (for the purposes of error reporting).
func errId(seq []byte) []byte {
const maxLen = 32
for i := 0; i < len(seq); {
if i > maxLen {
return append(seq[:i:i], "…"...)
}
r, size := utf8.DecodeRune(seq[i:])
if r > utf8.RuneSelf || (r != '/' && isDelim(byte(r))) {
if i == 0 {
// Either the first byte is invalid UTF-8 or a
// delimiter, or the first rune is non-ASCII.
// Return it as-is.
i = size
}
return seq[:i:i]
}
i += size
}
// No delimiter found.
return seq
}
// isDelim returns true if given byte is a delimiter character. // isDelim returns true if given byte is a delimiter character.
func isDelim(c byte) bool { func isDelim(c byte) bool {

View File

@ -50,8 +50,10 @@ type number struct {
// parseNumber constructs a number object from given input. It allows for the // parseNumber constructs a number object from given input. It allows for the
// following patterns: // following patterns:
//
// integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*) // integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*)
// float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?) // float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?)
//
// It also returns the number of parsed bytes for the given number, 0 if it is // It also returns the number of parsed bytes for the given number, 0 if it is
// not a number. // not a number.
func parseNumber(input []byte) number { func parseNumber(input []byte) number {

View File

@ -24,6 +24,6 @@
// the Go implementation should as well. // the Go implementation should as well.
// //
// The text format is almost a superset of JSON except: // The text format is almost a superset of JSON except:
// * message keys are not quoted strings, but identifiers // - message keys are not quoted strings, but identifiers
// * the top-level value must be a message without the delimiters // - the top-level value must be a message without the delimiters
package text package text

View File

@ -32,7 +32,6 @@ type Encoder struct {
encoderState encoderState
indent string indent string
newline string // set to "\n" if len(indent) > 0
delims [2]byte delims [2]byte
outputASCII bool outputASCII bool
} }
@ -61,7 +60,6 @@ func NewEncoder(indent string, delims [2]byte, outputASCII bool) (*Encoder, erro
return nil, errors.New("indent may only be composed of space and tab characters") return nil, errors.New("indent may only be composed of space and tab characters")
} }
e.indent = indent e.indent = indent
e.newline = "\n"
} }
switch delims { switch delims {
case [2]byte{0, 0}: case [2]byte{0, 0}:
@ -126,7 +124,7 @@ func appendString(out []byte, in string, outputASCII bool) []byte {
// are used to represent both the proto string and bytes type. // are used to represent both the proto string and bytes type.
r = rune(in[0]) r = rune(in[0])
fallthrough fallthrough
case r < ' ' || r == '"' || r == '\\': case r < ' ' || r == '"' || r == '\\' || r == 0x7f:
out = append(out, '\\') out = append(out, '\\')
switch r { switch r {
case '"', '\\': case '"', '\\':
@ -143,7 +141,7 @@ func appendString(out []byte, in string, outputASCII bool) []byte {
out = strconv.AppendUint(out, uint64(r), 16) out = strconv.AppendUint(out, uint64(r), 16)
} }
in = in[n:] in = in[n:]
case outputASCII && r >= utf8.RuneSelf: case r >= utf8.RuneSelf && (outputASCII || r <= 0x009f):
out = append(out, '\\') out = append(out, '\\')
if r <= math.MaxUint16 { if r <= math.MaxUint16 {
out = append(out, 'u') out = append(out, 'u')
@ -168,7 +166,7 @@ func appendString(out []byte, in string, outputASCII bool) []byte {
// escaping. If no characters need escaping, this returns the input length. // escaping. If no characters need escaping, this returns the input length.
func indexNeedEscapeInString(s string) int { func indexNeedEscapeInString(s string) int {
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
if c := s[i]; c < ' ' || c == '"' || c == '\'' || c == '\\' || c >= utf8.RuneSelf { if c := s[i]; c < ' ' || c == '"' || c == '\'' || c == '\\' || c >= 0x7f {
return i return i
} }
} }
@ -265,3 +263,8 @@ func (e *Encoder) Snapshot() encoderState {
func (e *Encoder) Reset(es encoderState) { func (e *Encoder) Reset(es encoderState) {
e.encoderState = es e.encoderState = es
} }
// AppendString appends the escaped form of the input string to b.
func AppendString(b []byte, s string) []byte {
return appendString(b, s, false)
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !go1.13
// +build !go1.13 // +build !go1.13
package errors package errors

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.13
// +build go1.13 // +build go1.13
package errors package errors

View File

@ -1,40 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package fieldsort defines an ordering of fields.
//
// The ordering defined by this package matches the historic behavior of the proto
// package, placing extensions first and oneofs last.
//
// There is no guarantee about stability of the wire encoding, and users should not
// depend on the order defined in this package as it is subject to change without
// notice.
package fieldsort
import (
"google.golang.org/protobuf/reflect/protoreflect"
)
// Less returns true if field a comes before field j in ordered wire marshal output.
func Less(a, b protoreflect.FieldDescriptor) bool {
ea := a.IsExtension()
eb := b.IsExtension()
oa := a.ContainingOneof()
ob := b.ContainingOneof()
switch {
case ea != eb:
return ea
case oa != nil && ob != nil:
if oa == ob {
return a.Number() < b.Number()
}
return oa.Index() < ob.Index()
case oa != nil && !oa.IsSynthetic():
return false
case ob != nil && !ob.IsSynthetic():
return true
default:
return a.Number() < b.Number()
}
}

View File

@ -3,14 +3,16 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package filedesc provides functionality for constructing descriptors. // Package filedesc provides functionality for constructing descriptors.
//
// The types in this package implement interfaces in the protoreflect package
// related to protobuf descripriptors.
package filedesc package filedesc
import ( import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry"
preg "google.golang.org/protobuf/reflect/protoregistry"
) )
// Builder construct a protoreflect.FileDescriptor from the raw descriptor. // Builder construct a protoreflect.FileDescriptor from the raw descriptor.
@ -35,7 +37,7 @@ type Builder struct {
// TypeResolver resolves extension field types for descriptor options. // TypeResolver resolves extension field types for descriptor options.
// If nil, it uses protoregistry.GlobalTypes. // If nil, it uses protoregistry.GlobalTypes.
TypeResolver interface { TypeResolver interface {
preg.ExtensionTypeResolver protoregistry.ExtensionTypeResolver
} }
// FileRegistry is use to lookup file, enum, and message dependencies. // FileRegistry is use to lookup file, enum, and message dependencies.
@ -43,8 +45,8 @@ type Builder struct {
// If nil, it uses protoregistry.GlobalFiles. // If nil, it uses protoregistry.GlobalFiles.
FileRegistry interface { FileRegistry interface {
FindFileByPath(string) (protoreflect.FileDescriptor, error) FindFileByPath(string) (protoreflect.FileDescriptor, error)
FindDescriptorByName(pref.FullName) (pref.Descriptor, error) FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
RegisterFile(pref.FileDescriptor) error RegisterFile(protoreflect.FileDescriptor) error
} }
} }
@ -52,8 +54,8 @@ type Builder struct {
// If so, it permits looking up an enum or message dependency based on the // If so, it permits looking up an enum or message dependency based on the
// sub-list and element index into filetype.Builder.DependencyIndexes. // sub-list and element index into filetype.Builder.DependencyIndexes.
type resolverByIndex interface { type resolverByIndex interface {
FindEnumByIndex(int32, int32, []Enum, []Message) pref.EnumDescriptor FindEnumByIndex(int32, int32, []Enum, []Message) protoreflect.EnumDescriptor
FindMessageByIndex(int32, int32, []Enum, []Message) pref.MessageDescriptor FindMessageByIndex(int32, int32, []Enum, []Message) protoreflect.MessageDescriptor
} }
// Indexes of each sub-list in filetype.Builder.DependencyIndexes. // Indexes of each sub-list in filetype.Builder.DependencyIndexes.
@ -67,7 +69,7 @@ const (
// Out is the output of the Builder. // Out is the output of the Builder.
type Out struct { type Out struct {
File pref.FileDescriptor File protoreflect.FileDescriptor
// Enums is all enum descriptors in "flattened ordering". // Enums is all enum descriptors in "flattened ordering".
Enums []Enum Enums []Enum
@ -94,10 +96,10 @@ func (db Builder) Build() (out Out) {
// Initialize resolvers and registries if unpopulated. // Initialize resolvers and registries if unpopulated.
if db.TypeResolver == nil { if db.TypeResolver == nil {
db.TypeResolver = preg.GlobalTypes db.TypeResolver = protoregistry.GlobalTypes
} }
if db.FileRegistry == nil { if db.FileRegistry == nil {
db.FileRegistry = preg.GlobalFiles db.FileRegistry = protoregistry.GlobalFiles
} }
fd := newRawFile(db) fd := newRawFile(db)

View File

@ -13,10 +13,11 @@ import (
"google.golang.org/protobuf/internal/descfmt" "google.golang.org/protobuf/internal/descfmt"
"google.golang.org/protobuf/internal/descopts" "google.golang.org/protobuf/internal/descopts"
"google.golang.org/protobuf/internal/encoding/defval" "google.golang.org/protobuf/internal/encoding/defval"
"google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
@ -42,9 +43,9 @@ type (
L2 *FileL2 L2 *FileL2
} }
FileL1 struct { FileL1 struct {
Syntax pref.Syntax Syntax protoreflect.Syntax
Path string Path string
Package pref.FullName Package protoreflect.FullName
Enums Enums Enums Enums
Messages Messages Messages Messages
@ -52,35 +53,35 @@ type (
Services Services Services Services
} }
FileL2 struct { FileL2 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Imports FileImports Imports FileImports
Locations SourceLocations Locations SourceLocations
} }
) )
func (fd *File) ParentFile() pref.FileDescriptor { return fd } func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
func (fd *File) Parent() pref.Descriptor { return nil } func (fd *File) Parent() protoreflect.Descriptor { return nil }
func (fd *File) Index() int { return 0 } func (fd *File) Index() int { return 0 }
func (fd *File) Syntax() pref.Syntax { return fd.L1.Syntax } func (fd *File) Syntax() protoreflect.Syntax { return fd.L1.Syntax }
func (fd *File) Name() pref.Name { return fd.L1.Package.Name() } func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() }
func (fd *File) FullName() pref.FullName { return fd.L1.Package } func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package }
func (fd *File) IsPlaceholder() bool { return false } func (fd *File) IsPlaceholder() bool { return false }
func (fd *File) Options() pref.ProtoMessage { func (fd *File) Options() protoreflect.ProtoMessage {
if f := fd.lazyInit().Options; f != nil { if f := fd.lazyInit().Options; f != nil {
return f() return f()
} }
return descopts.File return descopts.File
} }
func (fd *File) Path() string { return fd.L1.Path } func (fd *File) Path() string { return fd.L1.Path }
func (fd *File) Package() pref.FullName { return fd.L1.Package } func (fd *File) Package() protoreflect.FullName { return fd.L1.Package }
func (fd *File) Imports() pref.FileImports { return &fd.lazyInit().Imports } func (fd *File) Imports() protoreflect.FileImports { return &fd.lazyInit().Imports }
func (fd *File) Enums() pref.EnumDescriptors { return &fd.L1.Enums } func (fd *File) Enums() protoreflect.EnumDescriptors { return &fd.L1.Enums }
func (fd *File) Messages() pref.MessageDescriptors { return &fd.L1.Messages } func (fd *File) Messages() protoreflect.MessageDescriptors { return &fd.L1.Messages }
func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions } func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions }
func (fd *File) Services() pref.ServiceDescriptors { return &fd.L1.Services } func (fd *File) Services() protoreflect.ServiceDescriptors { return &fd.L1.Services }
func (fd *File) SourceLocations() pref.SourceLocations { return &fd.lazyInit().Locations } func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations }
func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) } func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
func (fd *File) ProtoType(pref.FileDescriptor) {} func (fd *File) ProtoType(protoreflect.FileDescriptor) {}
func (fd *File) ProtoInternal(pragma.DoNotImplement) {} func (fd *File) ProtoInternal(pragma.DoNotImplement) {}
func (fd *File) lazyInit() *FileL2 { func (fd *File) lazyInit() *FileL2 {
@ -99,15 +100,6 @@ func (fd *File) lazyInitOnce() {
fd.mu.Unlock() fd.mu.Unlock()
} }
// ProtoLegacyRawDesc is a pseudo-internal API for allowing the v1 code
// to be able to retrieve the raw descriptor.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *File) ProtoLegacyRawDesc() []byte {
return fd.builder.RawDescriptor
}
// GoPackagePath is a pseudo-internal API for determining the Go package path // GoPackagePath is a pseudo-internal API for determining the Go package path
// that this file descriptor is declared in. // that this file descriptor is declared in.
// //
@ -127,7 +119,7 @@ type (
eagerValues bool // controls whether EnumL2.Values is already populated eagerValues bool // controls whether EnumL2.Values is already populated
} }
EnumL2 struct { EnumL2 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Values EnumValues Values EnumValues
ReservedNames Names ReservedNames Names
ReservedRanges EnumRanges ReservedRanges EnumRanges
@ -138,41 +130,41 @@ type (
L1 EnumValueL1 L1 EnumValueL1
} }
EnumValueL1 struct { EnumValueL1 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Number pref.EnumNumber Number protoreflect.EnumNumber
} }
) )
func (ed *Enum) Options() pref.ProtoMessage { func (ed *Enum) Options() protoreflect.ProtoMessage {
if f := ed.lazyInit().Options; f != nil { if f := ed.lazyInit().Options; f != nil {
return f() return f()
} }
return descopts.Enum return descopts.Enum
} }
func (ed *Enum) Values() pref.EnumValueDescriptors { func (ed *Enum) Values() protoreflect.EnumValueDescriptors {
if ed.L1.eagerValues { if ed.L1.eagerValues {
return &ed.L2.Values return &ed.L2.Values
} }
return &ed.lazyInit().Values return &ed.lazyInit().Values
} }
func (ed *Enum) ReservedNames() pref.Names { return &ed.lazyInit().ReservedNames } func (ed *Enum) ReservedNames() protoreflect.Names { return &ed.lazyInit().ReservedNames }
func (ed *Enum) ReservedRanges() pref.EnumRanges { return &ed.lazyInit().ReservedRanges } func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges }
func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) } func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
func (ed *Enum) ProtoType(pref.EnumDescriptor) {} func (ed *Enum) ProtoType(protoreflect.EnumDescriptor) {}
func (ed *Enum) lazyInit() *EnumL2 { func (ed *Enum) lazyInit() *EnumL2 {
ed.L0.ParentFile.lazyInit() // implicitly initializes L2 ed.L0.ParentFile.lazyInit() // implicitly initializes L2
return ed.L2 return ed.L2
} }
func (ed *EnumValue) Options() pref.ProtoMessage { func (ed *EnumValue) Options() protoreflect.ProtoMessage {
if f := ed.L1.Options; f != nil { if f := ed.L1.Options; f != nil {
return f() return f()
} }
return descopts.EnumValue return descopts.EnumValue
} }
func (ed *EnumValue) Number() pref.EnumNumber { return ed.L1.Number } func (ed *EnumValue) Number() protoreflect.EnumNumber { return ed.L1.Number }
func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) } func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) }
func (ed *EnumValue) ProtoType(pref.EnumValueDescriptor) {} func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {}
type ( type (
Message struct { Message struct {
@ -188,14 +180,14 @@ type (
IsMessageSet bool // promoted from google.protobuf.MessageOptions IsMessageSet bool // promoted from google.protobuf.MessageOptions
} }
MessageL2 struct { MessageL2 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Fields Fields Fields Fields
Oneofs Oneofs Oneofs Oneofs
ReservedNames Names ReservedNames Names
ReservedRanges FieldRanges ReservedRanges FieldRanges
RequiredNumbers FieldNumbers // must be consistent with Fields.Cardinality RequiredNumbers FieldNumbers // must be consistent with Fields.Cardinality
ExtensionRanges FieldRanges ExtensionRanges FieldRanges
ExtensionRangeOptions []func() pref.ProtoMessage // must be same length as ExtensionRanges ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges
} }
Field struct { Field struct {
@ -203,11 +195,11 @@ type (
L1 FieldL1 L1 FieldL1
} }
FieldL1 struct { FieldL1 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Number pref.FieldNumber Number protoreflect.FieldNumber
Cardinality pref.Cardinality // must be consistent with Message.RequiredNumbers Cardinality protoreflect.Cardinality // must be consistent with Message.RequiredNumbers
Kind pref.Kind Kind protoreflect.Kind
JSONName jsonName StringName stringName
IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
IsWeak bool // promoted from google.protobuf.FieldOptions IsWeak bool // promoted from google.protobuf.FieldOptions
HasPacked bool // promoted from google.protobuf.FieldOptions HasPacked bool // promoted from google.protobuf.FieldOptions
@ -215,9 +207,9 @@ type (
HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions
EnforceUTF8 bool // promoted from google.protobuf.FieldOptions EnforceUTF8 bool // promoted from google.protobuf.FieldOptions
Default defaultValue Default defaultValue
ContainingOneof pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
Enum pref.EnumDescriptor Enum protoreflect.EnumDescriptor
Message pref.MessageDescriptor Message protoreflect.MessageDescriptor
} }
Oneof struct { Oneof struct {
@ -225,34 +217,34 @@ type (
L1 OneofL1 L1 OneofL1
} }
OneofL1 struct { OneofL1 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Fields OneofFields // must be consistent with Message.Fields.ContainingOneof Fields OneofFields // must be consistent with Message.Fields.ContainingOneof
} }
) )
func (md *Message) Options() pref.ProtoMessage { func (md *Message) Options() protoreflect.ProtoMessage {
if f := md.lazyInit().Options; f != nil { if f := md.lazyInit().Options; f != nil {
return f() return f()
} }
return descopts.Message return descopts.Message
} }
func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry } func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry }
func (md *Message) Fields() pref.FieldDescriptors { return &md.lazyInit().Fields } func (md *Message) Fields() protoreflect.FieldDescriptors { return &md.lazyInit().Fields }
func (md *Message) Oneofs() pref.OneofDescriptors { return &md.lazyInit().Oneofs } func (md *Message) Oneofs() protoreflect.OneofDescriptors { return &md.lazyInit().Oneofs }
func (md *Message) ReservedNames() pref.Names { return &md.lazyInit().ReservedNames } func (md *Message) ReservedNames() protoreflect.Names { return &md.lazyInit().ReservedNames }
func (md *Message) ReservedRanges() pref.FieldRanges { return &md.lazyInit().ReservedRanges } func (md *Message) ReservedRanges() protoreflect.FieldRanges { return &md.lazyInit().ReservedRanges }
func (md *Message) RequiredNumbers() pref.FieldNumbers { return &md.lazyInit().RequiredNumbers } func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers }
func (md *Message) ExtensionRanges() pref.FieldRanges { return &md.lazyInit().ExtensionRanges } func (md *Message) ExtensionRanges() protoreflect.FieldRanges { return &md.lazyInit().ExtensionRanges }
func (md *Message) ExtensionRangeOptions(i int) pref.ProtoMessage { func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage {
if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil { if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
return f() return f()
} }
return descopts.ExtensionRange return descopts.ExtensionRange
} }
func (md *Message) Enums() pref.EnumDescriptors { return &md.L1.Enums } func (md *Message) Enums() protoreflect.EnumDescriptors { return &md.L1.Enums }
func (md *Message) Messages() pref.MessageDescriptors { return &md.L1.Messages } func (md *Message) Messages() protoreflect.MessageDescriptors { return &md.L1.Messages }
func (md *Message) Extensions() pref.ExtensionDescriptors { return &md.L1.Extensions } func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions }
func (md *Message) ProtoType(pref.MessageDescriptor) {} func (md *Message) ProtoType(protoreflect.MessageDescriptor) {}
func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) } func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
func (md *Message) lazyInit() *MessageL2 { func (md *Message) lazyInit() *MessageL2 {
md.L0.ParentFile.lazyInit() // implicitly initializes L2 md.L0.ParentFile.lazyInit() // implicitly initializes L2
@ -268,27 +260,28 @@ func (md *Message) IsMessageSet() bool {
return md.L1.IsMessageSet return md.L1.IsMessageSet
} }
func (fd *Field) Options() pref.ProtoMessage { func (fd *Field) Options() protoreflect.ProtoMessage {
if f := fd.L1.Options; f != nil { if f := fd.L1.Options; f != nil {
return f() return f()
} }
return descopts.Field return descopts.Field
} }
func (fd *Field) Number() pref.FieldNumber { return fd.L1.Number } func (fd *Field) Number() protoreflect.FieldNumber { return fd.L1.Number }
func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality } func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality }
func (fd *Field) Kind() pref.Kind { return fd.L1.Kind } func (fd *Field) Kind() protoreflect.Kind { return fd.L1.Kind }
func (fd *Field) HasJSONName() bool { return fd.L1.JSONName.has } func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON }
func (fd *Field) JSONName() string { return fd.L1.JSONName.get(fd) } func (fd *Field) JSONName() string { return fd.L1.StringName.getJSON(fd) }
func (fd *Field) TextName() string { return fd.L1.StringName.getText(fd) }
func (fd *Field) HasPresence() bool { func (fd *Field) HasPresence() bool {
return fd.L1.Cardinality != pref.Repeated && (fd.L0.ParentFile.L1.Syntax == pref.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil) return fd.L1.Cardinality != protoreflect.Repeated && (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
} }
func (fd *Field) HasOptionalKeyword() bool { func (fd *Field) HasOptionalKeyword() bool {
return (fd.L0.ParentFile.L1.Syntax == pref.Proto2 && fd.L1.Cardinality == pref.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
} }
func (fd *Field) IsPacked() bool { func (fd *Field) IsPacked() bool {
if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated { if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Repeated {
switch fd.L1.Kind { switch fd.L1.Kind {
case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind: case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
default: default:
return true return true
} }
@ -297,40 +290,40 @@ func (fd *Field) IsPacked() bool {
} }
func (fd *Field) IsExtension() bool { return false } func (fd *Field) IsExtension() bool { return false }
func (fd *Field) IsWeak() bool { return fd.L1.IsWeak } func (fd *Field) IsWeak() bool { return fd.L1.IsWeak }
func (fd *Field) IsList() bool { return fd.Cardinality() == pref.Repeated && !fd.IsMap() } func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() } func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() }
func (fd *Field) MapKey() pref.FieldDescriptor { func (fd *Field) MapKey() protoreflect.FieldDescriptor {
if !fd.IsMap() { if !fd.IsMap() {
return nil return nil
} }
return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number) return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
} }
func (fd *Field) MapValue() pref.FieldDescriptor { func (fd *Field) MapValue() protoreflect.FieldDescriptor {
if !fd.IsMap() { if !fd.IsMap() {
return nil return nil
} }
return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number) return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
} }
func (fd *Field) HasDefault() bool { return fd.L1.Default.has } func (fd *Field) HasDefault() bool { return fd.L1.Default.has }
func (fd *Field) Default() pref.Value { return fd.L1.Default.get(fd) } func (fd *Field) Default() protoreflect.Value { return fd.L1.Default.get(fd) }
func (fd *Field) DefaultEnumValue() pref.EnumValueDescriptor { return fd.L1.Default.enum } func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum }
func (fd *Field) ContainingOneof() pref.OneofDescriptor { return fd.L1.ContainingOneof } func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor { return fd.L1.ContainingOneof }
func (fd *Field) ContainingMessage() pref.MessageDescriptor { func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor {
return fd.L0.Parent.(pref.MessageDescriptor) return fd.L0.Parent.(protoreflect.MessageDescriptor)
} }
func (fd *Field) Enum() pref.EnumDescriptor { func (fd *Field) Enum() protoreflect.EnumDescriptor {
return fd.L1.Enum return fd.L1.Enum
} }
func (fd *Field) Message() pref.MessageDescriptor { func (fd *Field) Message() protoreflect.MessageDescriptor {
if fd.L1.IsWeak { if fd.L1.IsWeak {
if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil { if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
return d.(pref.MessageDescriptor) return d.(protoreflect.MessageDescriptor)
} }
} }
return fd.L1.Message return fd.L1.Message
} }
func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) } func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) }
func (fd *Field) ProtoType(pref.FieldDescriptor) {} func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}
// EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8 // EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
// validation for the string field. This exists for Google-internal use only // validation for the string field. This exists for Google-internal use only
@ -343,21 +336,21 @@ func (fd *Field) EnforceUTF8() bool {
if fd.L1.HasEnforceUTF8 { if fd.L1.HasEnforceUTF8 {
return fd.L1.EnforceUTF8 return fd.L1.EnforceUTF8
} }
return fd.L0.ParentFile.L1.Syntax == pref.Proto3 return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3
} }
func (od *Oneof) IsSynthetic() bool { func (od *Oneof) IsSynthetic() bool {
return od.L0.ParentFile.L1.Syntax == pref.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword() return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
} }
func (od *Oneof) Options() pref.ProtoMessage { func (od *Oneof) Options() protoreflect.ProtoMessage {
if f := od.L1.Options; f != nil { if f := od.L1.Options; f != nil {
return f() return f()
} }
return descopts.Oneof return descopts.Oneof
} }
func (od *Oneof) Fields() pref.FieldDescriptors { return &od.L1.Fields } func (od *Oneof) Fields() protoreflect.FieldDescriptors { return &od.L1.Fields }
func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) } func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) }
func (od *Oneof) ProtoType(pref.OneofDescriptor) {} func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {}
type ( type (
Extension struct { Extension struct {
@ -366,53 +359,56 @@ type (
L2 *ExtensionL2 // protected by fileDesc.once L2 *ExtensionL2 // protected by fileDesc.once
} }
ExtensionL1 struct { ExtensionL1 struct {
Number pref.FieldNumber Number protoreflect.FieldNumber
Extendee pref.MessageDescriptor Extendee protoreflect.MessageDescriptor
Cardinality pref.Cardinality Cardinality protoreflect.Cardinality
Kind pref.Kind Kind protoreflect.Kind
} }
ExtensionL2 struct { ExtensionL2 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
JSONName jsonName StringName stringName
IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
IsPacked bool // promoted from google.protobuf.FieldOptions IsPacked bool // promoted from google.protobuf.FieldOptions
Default defaultValue Default defaultValue
Enum pref.EnumDescriptor Enum protoreflect.EnumDescriptor
Message pref.MessageDescriptor Message protoreflect.MessageDescriptor
} }
) )
func (xd *Extension) Options() pref.ProtoMessage { func (xd *Extension) Options() protoreflect.ProtoMessage {
if f := xd.lazyInit().Options; f != nil { if f := xd.lazyInit().Options; f != nil {
return f() return f()
} }
return descopts.Field return descopts.Field
} }
func (xd *Extension) Number() pref.FieldNumber { return xd.L1.Number } func (xd *Extension) Number() protoreflect.FieldNumber { return xd.L1.Number }
func (xd *Extension) Cardinality() pref.Cardinality { return xd.L1.Cardinality } func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality }
func (xd *Extension) Kind() pref.Kind { return xd.L1.Kind } func (xd *Extension) Kind() protoreflect.Kind { return xd.L1.Kind }
func (xd *Extension) HasJSONName() bool { return xd.lazyInit().JSONName.has } func (xd *Extension) HasJSONName() bool { return xd.lazyInit().StringName.hasJSON }
func (xd *Extension) JSONName() string { return xd.lazyInit().JSONName.get(xd) } func (xd *Extension) JSONName() string { return xd.lazyInit().StringName.getJSON(xd) }
func (xd *Extension) HasPresence() bool { return xd.L1.Cardinality != pref.Repeated } func (xd *Extension) TextName() string { return xd.lazyInit().StringName.getText(xd) }
func (xd *Extension) HasPresence() bool { return xd.L1.Cardinality != protoreflect.Repeated }
func (xd *Extension) HasOptionalKeyword() bool { func (xd *Extension) HasOptionalKeyword() bool {
return (xd.L0.ParentFile.L1.Syntax == pref.Proto2 && xd.L1.Cardinality == pref.Optional) || xd.lazyInit().IsProto3Optional return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
} }
func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked } func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked }
func (xd *Extension) IsExtension() bool { return true } func (xd *Extension) IsExtension() bool { return true }
func (xd *Extension) IsWeak() bool { return false } func (xd *Extension) IsWeak() bool { return false }
func (xd *Extension) IsList() bool { return xd.Cardinality() == pref.Repeated } func (xd *Extension) IsList() bool { return xd.Cardinality() == protoreflect.Repeated }
func (xd *Extension) IsMap() bool { return false } func (xd *Extension) IsMap() bool { return false }
func (xd *Extension) MapKey() pref.FieldDescriptor { return nil } func (xd *Extension) MapKey() protoreflect.FieldDescriptor { return nil }
func (xd *Extension) MapValue() pref.FieldDescriptor { return nil } func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil }
func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has } func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has }
func (xd *Extension) Default() pref.Value { return xd.lazyInit().Default.get(xd) } func (xd *Extension) Default() protoreflect.Value { return xd.lazyInit().Default.get(xd) }
func (xd *Extension) DefaultEnumValue() pref.EnumValueDescriptor { return xd.lazyInit().Default.enum } func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor {
func (xd *Extension) ContainingOneof() pref.OneofDescriptor { return nil } return xd.lazyInit().Default.enum
func (xd *Extension) ContainingMessage() pref.MessageDescriptor { return xd.L1.Extendee } }
func (xd *Extension) Enum() pref.EnumDescriptor { return xd.lazyInit().Enum } func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor { return nil }
func (xd *Extension) Message() pref.MessageDescriptor { return xd.lazyInit().Message } func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee }
func (xd *Extension) Enum() protoreflect.EnumDescriptor { return xd.lazyInit().Enum }
func (xd *Extension) Message() protoreflect.MessageDescriptor { return xd.lazyInit().Message }
func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) } func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) }
func (xd *Extension) ProtoType(pref.FieldDescriptor) {} func (xd *Extension) ProtoType(protoreflect.FieldDescriptor) {}
func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {} func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {}
func (xd *Extension) lazyInit() *ExtensionL2 { func (xd *Extension) lazyInit() *ExtensionL2 {
xd.L0.ParentFile.lazyInit() // implicitly initializes L2 xd.L0.ParentFile.lazyInit() // implicitly initializes L2
@ -427,7 +423,7 @@ type (
} }
ServiceL1 struct{} ServiceL1 struct{}
ServiceL2 struct { ServiceL2 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Methods Methods Methods Methods
} }
@ -436,48 +432,48 @@ type (
L1 MethodL1 L1 MethodL1
} }
MethodL1 struct { MethodL1 struct {
Options func() pref.ProtoMessage Options func() protoreflect.ProtoMessage
Input pref.MessageDescriptor Input protoreflect.MessageDescriptor
Output pref.MessageDescriptor Output protoreflect.MessageDescriptor
IsStreamingClient bool IsStreamingClient bool
IsStreamingServer bool IsStreamingServer bool
} }
) )
func (sd *Service) Options() pref.ProtoMessage { func (sd *Service) Options() protoreflect.ProtoMessage {
if f := sd.lazyInit().Options; f != nil { if f := sd.lazyInit().Options; f != nil {
return f() return f()
} }
return descopts.Service return descopts.Service
} }
func (sd *Service) Methods() pref.MethodDescriptors { return &sd.lazyInit().Methods } func (sd *Service) Methods() protoreflect.MethodDescriptors { return &sd.lazyInit().Methods }
func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) } func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) }
func (sd *Service) ProtoType(pref.ServiceDescriptor) {} func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {}
func (sd *Service) ProtoInternal(pragma.DoNotImplement) {} func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
func (sd *Service) lazyInit() *ServiceL2 { func (sd *Service) lazyInit() *ServiceL2 {
sd.L0.ParentFile.lazyInit() // implicitly initializes L2 sd.L0.ParentFile.lazyInit() // implicitly initializes L2
return sd.L2 return sd.L2
} }
func (md *Method) Options() pref.ProtoMessage { func (md *Method) Options() protoreflect.ProtoMessage {
if f := md.L1.Options; f != nil { if f := md.L1.Options; f != nil {
return f() return f()
} }
return descopts.Method return descopts.Method
} }
func (md *Method) Input() pref.MessageDescriptor { return md.L1.Input } func (md *Method) Input() protoreflect.MessageDescriptor { return md.L1.Input }
func (md *Method) Output() pref.MessageDescriptor { return md.L1.Output } func (md *Method) Output() protoreflect.MessageDescriptor { return md.L1.Output }
func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient } func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient }
func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer } func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer }
func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) } func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) }
func (md *Method) ProtoType(pref.MethodDescriptor) {} func (md *Method) ProtoType(protoreflect.MethodDescriptor) {}
func (md *Method) ProtoInternal(pragma.DoNotImplement) {} func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
// Surrogate files are can be used to create standalone descriptors // Surrogate files are can be used to create standalone descriptors
// where the syntax is only information derived from the parent file. // where the syntax is only information derived from the parent file.
var ( var (
SurrogateProto2 = &File{L1: FileL1{Syntax: pref.Proto2}, L2: &FileL2{}} SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
SurrogateProto3 = &File{L1: FileL1{Syntax: pref.Proto3}, L2: &FileL2{}} SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
) )
type ( type (
@ -485,49 +481,72 @@ type (
L0 BaseL0 L0 BaseL0
} }
BaseL0 struct { BaseL0 struct {
FullName pref.FullName // must be populated FullName protoreflect.FullName // must be populated
ParentFile *File // must be populated ParentFile *File // must be populated
Parent pref.Descriptor Parent protoreflect.Descriptor
Index int Index int
} }
) )
func (d *Base) Name() pref.Name { return d.L0.FullName.Name() } func (d *Base) Name() protoreflect.Name { return d.L0.FullName.Name() }
func (d *Base) FullName() pref.FullName { return d.L0.FullName } func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName }
func (d *Base) ParentFile() pref.FileDescriptor { func (d *Base) ParentFile() protoreflect.FileDescriptor {
if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 { if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
return nil // surrogate files are not real parents return nil // surrogate files are not real parents
} }
return d.L0.ParentFile return d.L0.ParentFile
} }
func (d *Base) Parent() pref.Descriptor { return d.L0.Parent } func (d *Base) Parent() protoreflect.Descriptor { return d.L0.Parent }
func (d *Base) Index() int { return d.L0.Index } func (d *Base) Index() int { return d.L0.Index }
func (d *Base) Syntax() pref.Syntax { return d.L0.ParentFile.Syntax() } func (d *Base) Syntax() protoreflect.Syntax { return d.L0.ParentFile.Syntax() }
func (d *Base) IsPlaceholder() bool { return false } func (d *Base) IsPlaceholder() bool { return false }
func (d *Base) ProtoInternal(pragma.DoNotImplement) {} func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
type jsonName struct { type stringName struct {
has bool hasJSON bool
once sync.Once once sync.Once
name string nameJSON string
nameText string
} }
// Init initializes the name. It is exported for use by other internal packages. // InitJSON initializes the name. It is exported for use by other internal packages.
func (js *jsonName) Init(s string) { func (s *stringName) InitJSON(name string) {
js.has = true s.hasJSON = true
js.name = s s.nameJSON = name
} }
func (js *jsonName) get(fd pref.FieldDescriptor) string { func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
if !js.has { s.once.Do(func() {
js.once.Do(func() { if fd.IsExtension() {
js.name = strs.JSONCamelCase(string(fd.Name())) // For extensions, JSON and text are formatted the same way.
}) var name string
if messageset.IsMessageSetExtension(fd) {
name = string("[" + fd.FullName().Parent() + "]")
} else {
name = string("[" + fd.FullName() + "]")
} }
return js.name s.nameJSON = name
s.nameText = name
} else {
// Format the JSON name.
if !s.hasJSON {
s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
}
// Format the text name.
s.nameText = string(fd.Name())
if fd.Kind() == protoreflect.GroupKind {
s.nameText = string(fd.Message().Name())
}
}
})
return s
} }
func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue { func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText }
func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue {
dv := defaultValue{has: v.IsValid(), val: v, enum: ev} dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
if b, ok := v.Interface().([]byte); ok { if b, ok := v.Interface().([]byte); ok {
// Store a copy of the default bytes, so that we can detect // Store a copy of the default bytes, so that we can detect
@ -537,9 +556,9 @@ func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue {
return dv return dv
} }
func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) defaultValue { func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue {
var evs pref.EnumValueDescriptors var evs protoreflect.EnumValueDescriptors
if k == pref.EnumKind { if k == protoreflect.EnumKind {
// If the enum is declared within the same file, be careful not to // If the enum is declared within the same file, be careful not to
// blindly call the Values method, lest we bind ourselves in a deadlock. // blindly call the Values method, lest we bind ourselves in a deadlock.
if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf { if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
@ -550,9 +569,9 @@ func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) d
// If we are unable to resolve the enum dependency, use a placeholder // If we are unable to resolve the enum dependency, use a placeholder
// enum value since we will not be able to parse the default value. // enum value since we will not be able to parse the default value.
if ed.IsPlaceholder() && pref.Name(b).IsValid() { if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() {
v := pref.ValueOfEnum(0) v := protoreflect.ValueOfEnum(0)
ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b))) ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b)))
return DefaultValue(v, ev) return DefaultValue(v, ev)
} }
} }
@ -566,41 +585,41 @@ func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) d
type defaultValue struct { type defaultValue struct {
has bool has bool
val pref.Value val protoreflect.Value
enum pref.EnumValueDescriptor enum protoreflect.EnumValueDescriptor
bytes []byte bytes []byte
} }
func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value { func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value {
// Return the zero value as the default if unpopulated. // Return the zero value as the default if unpopulated.
if !dv.has { if !dv.has {
if fd.Cardinality() == pref.Repeated { if fd.Cardinality() == protoreflect.Repeated {
return pref.Value{} return protoreflect.Value{}
} }
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
return pref.ValueOfBool(false) return protoreflect.ValueOfBool(false)
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
return pref.ValueOfInt32(0) return protoreflect.ValueOfInt32(0)
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
return pref.ValueOfInt64(0) return protoreflect.ValueOfInt64(0)
case pref.Uint32Kind, pref.Fixed32Kind: case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
return pref.ValueOfUint32(0) return protoreflect.ValueOfUint32(0)
case pref.Uint64Kind, pref.Fixed64Kind: case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
return pref.ValueOfUint64(0) return protoreflect.ValueOfUint64(0)
case pref.FloatKind: case protoreflect.FloatKind:
return pref.ValueOfFloat32(0) return protoreflect.ValueOfFloat32(0)
case pref.DoubleKind: case protoreflect.DoubleKind:
return pref.ValueOfFloat64(0) return protoreflect.ValueOfFloat64(0)
case pref.StringKind: case protoreflect.StringKind:
return pref.ValueOfString("") return protoreflect.ValueOfString("")
case pref.BytesKind: case protoreflect.BytesKind:
return pref.ValueOfBytes(nil) return protoreflect.ValueOfBytes(nil)
case pref.EnumKind: case protoreflect.EnumKind:
if evs := fd.Enum().Values(); evs.Len() > 0 { if evs := fd.Enum().Values(); evs.Len() > 0 {
return pref.ValueOfEnum(evs.Get(0).Number()) return protoreflect.ValueOfEnum(evs.Get(0).Number())
} }
return pref.ValueOfEnum(0) return protoreflect.ValueOfEnum(0)
} }
} }

View File

@ -10,7 +10,7 @@ import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
// fileRaw is a data struct used when initializing a file descriptor from // fileRaw is a data struct used when initializing a file descriptor from
@ -95,7 +95,7 @@ func (fd *File) unmarshalSeed(b []byte) {
sb := getBuilder() sb := getBuilder()
defer putBuilder(sb) defer putBuilder(sb)
var prevField pref.FieldNumber var prevField protoreflect.FieldNumber
var numEnums, numMessages, numExtensions, numServices int var numEnums, numMessages, numExtensions, numServices int
var posEnums, posMessages, posExtensions, posServices int var posEnums, posMessages, posExtensions, posServices int
b0 := b b0 := b
@ -110,16 +110,16 @@ func (fd *File) unmarshalSeed(b []byte) {
case genid.FileDescriptorProto_Syntax_field_number: case genid.FileDescriptorProto_Syntax_field_number:
switch string(v) { switch string(v) {
case "proto2": case "proto2":
fd.L1.Syntax = pref.Proto2 fd.L1.Syntax = protoreflect.Proto2
case "proto3": case "proto3":
fd.L1.Syntax = pref.Proto3 fd.L1.Syntax = protoreflect.Proto3
default: default:
panic("invalid syntax") panic("invalid syntax")
} }
case genid.FileDescriptorProto_Name_field_number: case genid.FileDescriptorProto_Name_field_number:
fd.L1.Path = sb.MakeString(v) fd.L1.Path = sb.MakeString(v)
case genid.FileDescriptorProto_Package_field_number: case genid.FileDescriptorProto_Package_field_number:
fd.L1.Package = pref.FullName(sb.MakeString(v)) fd.L1.Package = protoreflect.FullName(sb.MakeString(v))
case genid.FileDescriptorProto_EnumType_field_number: case genid.FileDescriptorProto_EnumType_field_number:
if prevField != genid.FileDescriptorProto_EnumType_field_number { if prevField != genid.FileDescriptorProto_EnumType_field_number {
if numEnums > 0 { if numEnums > 0 {
@ -163,7 +163,7 @@ func (fd *File) unmarshalSeed(b []byte) {
// If syntax is missing, it is assumed to be proto2. // If syntax is missing, it is assumed to be proto2.
if fd.L1.Syntax == 0 { if fd.L1.Syntax == 0 {
fd.L1.Syntax = pref.Proto2 fd.L1.Syntax = protoreflect.Proto2
} }
// Must allocate all declarations before parsing each descriptor type // Must allocate all declarations before parsing each descriptor type
@ -219,7 +219,7 @@ func (fd *File) unmarshalSeed(b []byte) {
} }
} }
func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
ed.L0.ParentFile = pf ed.L0.ParentFile = pf
ed.L0.Parent = pd ed.L0.Parent = pd
ed.L0.Index = i ed.L0.Index = i
@ -271,12 +271,12 @@ func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Desc
} }
} }
func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
md.L0.ParentFile = pf md.L0.ParentFile = pf
md.L0.Parent = pd md.L0.Parent = pd
md.L0.Index = i md.L0.Index = i
var prevField pref.FieldNumber var prevField protoreflect.FieldNumber
var numEnums, numMessages, numExtensions int var numEnums, numMessages, numExtensions int
var posEnums, posMessages, posExtensions int var posEnums, posMessages, posExtensions int
b0 := b b0 := b
@ -387,7 +387,7 @@ func (md *Message) unmarshalSeedOptions(b []byte) {
} }
} }
func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
xd.L0.ParentFile = pf xd.L0.ParentFile = pf
xd.L0.Parent = pd xd.L0.Parent = pd
xd.L0.Index = i xd.L0.Index = i
@ -401,11 +401,11 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref
b = b[m:] b = b[m:]
switch num { switch num {
case genid.FieldDescriptorProto_Number_field_number: case genid.FieldDescriptorProto_Number_field_number:
xd.L1.Number = pref.FieldNumber(v) xd.L1.Number = protoreflect.FieldNumber(v)
case genid.FieldDescriptorProto_Label_field_number: case genid.FieldDescriptorProto_Label_field_number:
xd.L1.Cardinality = pref.Cardinality(v) xd.L1.Cardinality = protoreflect.Cardinality(v)
case genid.FieldDescriptorProto_Type_field_number: case genid.FieldDescriptorProto_Type_field_number:
xd.L1.Kind = pref.Kind(v) xd.L1.Kind = protoreflect.Kind(v)
} }
case protowire.BytesType: case protowire.BytesType:
v, m := protowire.ConsumeBytes(b) v, m := protowire.ConsumeBytes(b)
@ -423,7 +423,7 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref
} }
} }
func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
sd.L0.ParentFile = pf sd.L0.ParentFile = pf
sd.L0.Parent = pd sd.L0.Parent = pd
sd.L0.Index = i sd.L0.Index = i
@ -459,13 +459,13 @@ func putBuilder(b *strs.Builder) {
// makeFullName converts b to a protoreflect.FullName, // makeFullName converts b to a protoreflect.FullName,
// where b must start with a leading dot. // where b must start with a leading dot.
func makeFullName(sb *strs.Builder, b []byte) pref.FullName { func makeFullName(sb *strs.Builder, b []byte) protoreflect.FullName {
if len(b) == 0 || b[0] != '.' { if len(b) == 0 || b[0] != '.' {
panic("name reference must be fully qualified") panic("name reference must be fully qualified")
} }
return pref.FullName(sb.MakeString(b[1:])) return protoreflect.FullName(sb.MakeString(b[1:]))
} }
func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName { func appendFullName(sb *strs.Builder, prefix protoreflect.FullName, suffix []byte) protoreflect.FullName {
return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix))) return sb.AppendFullName(prefix, protoreflect.Name(strs.UnsafeString(suffix)))
} }

View File

@ -13,7 +13,7 @@ import (
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
func (fd *File) lazyRawInit() { func (fd *File) lazyRawInit() {
@ -39,10 +39,10 @@ func (file *File) resolveMessages() {
// Resolve message field dependency. // Resolve message field dependency.
switch fd.L1.Kind { switch fd.L1.Kind {
case pref.EnumKind: case protoreflect.EnumKind:
fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx) fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx)
depIdx++ depIdx++
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx) fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx)
depIdx++ depIdx++
} }
@ -62,10 +62,10 @@ func (file *File) resolveExtensions() {
// Resolve extension field dependency. // Resolve extension field dependency.
switch xd.L1.Kind { switch xd.L1.Kind {
case pref.EnumKind: case protoreflect.EnumKind:
xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx) xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx)
depIdx++ depIdx++
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx) xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx)
depIdx++ depIdx++
} }
@ -92,7 +92,7 @@ func (file *File) resolveServices() {
} }
} }
func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor { func (file *File) resolveEnumDependency(ed protoreflect.EnumDescriptor, i, j int32) protoreflect.EnumDescriptor {
r := file.builder.FileRegistry r := file.builder.FileRegistry
if r, ok := r.(resolverByIndex); ok { if r, ok := r.(resolverByIndex); ok {
if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil { if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil {
@ -105,12 +105,12 @@ func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref
} }
} }
if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil { if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil {
return d.(pref.EnumDescriptor) return d.(protoreflect.EnumDescriptor)
} }
return ed return ed
} }
func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor { func (file *File) resolveMessageDependency(md protoreflect.MessageDescriptor, i, j int32) protoreflect.MessageDescriptor {
r := file.builder.FileRegistry r := file.builder.FileRegistry
if r, ok := r.(resolverByIndex); ok { if r, ok := r.(resolverByIndex); ok {
if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil { if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil {
@ -123,7 +123,7 @@ func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32
} }
} }
if d, _ := r.FindDescriptorByName(md.FullName()); d != nil { if d, _ := r.FindDescriptorByName(md.FullName()); d != nil {
return d.(pref.MessageDescriptor) return d.(protoreflect.MessageDescriptor)
} }
return md return md
} }
@ -158,7 +158,7 @@ func (fd *File) unmarshalFull(b []byte) {
if imp == nil { if imp == nil {
imp = PlaceholderFile(path) imp = PlaceholderFile(path)
} }
fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp}) fd.L2.Imports = append(fd.L2.Imports, protoreflect.FileImport{FileDescriptor: imp})
case genid.FileDescriptorProto_EnumType_field_number: case genid.FileDescriptorProto_EnumType_field_number:
fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb) fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb)
enumIdx++ enumIdx++
@ -199,7 +199,7 @@ func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
case genid.EnumDescriptorProto_Value_field_number: case genid.EnumDescriptorProto_Value_field_number:
rawValues = append(rawValues, v) rawValues = append(rawValues, v)
case genid.EnumDescriptorProto_ReservedName_field_number: case genid.EnumDescriptorProto_ReservedName_field_number:
ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v))) ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v)))
case genid.EnumDescriptorProto_ReservedRange_field_number: case genid.EnumDescriptorProto_ReservedRange_field_number:
ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v)) ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v))
case genid.EnumDescriptorProto_Options_field_number: case genid.EnumDescriptorProto_Options_field_number:
@ -219,7 +219,7 @@ func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) {
ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions) ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions)
} }
func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) { func unmarshalEnumReservedRange(b []byte) (r [2]protoreflect.EnumNumber) {
for len(b) > 0 { for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b) num, typ, n := protowire.ConsumeTag(b)
b = b[n:] b = b[n:]
@ -229,9 +229,9 @@ func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
b = b[m:] b = b[m:]
switch num { switch num {
case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number: case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number:
r[0] = pref.EnumNumber(v) r[0] = protoreflect.EnumNumber(v)
case genid.EnumDescriptorProto_EnumReservedRange_End_field_number: case genid.EnumDescriptorProto_EnumReservedRange_End_field_number:
r[1] = pref.EnumNumber(v) r[1] = protoreflect.EnumNumber(v)
} }
default: default:
m := protowire.ConsumeFieldValue(num, typ, b) m := protowire.ConsumeFieldValue(num, typ, b)
@ -241,7 +241,7 @@ func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
return r return r
} }
func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
vd.L0.ParentFile = pf vd.L0.ParentFile = pf
vd.L0.Parent = pd vd.L0.Parent = pd
vd.L0.Index = i vd.L0.Index = i
@ -256,7 +256,7 @@ func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref
b = b[m:] b = b[m:]
switch num { switch num {
case genid.EnumValueDescriptorProto_Number_field_number: case genid.EnumValueDescriptorProto_Number_field_number:
vd.L1.Number = pref.EnumNumber(v) vd.L1.Number = protoreflect.EnumNumber(v)
} }
case protowire.BytesType: case protowire.BytesType:
v, m := protowire.ConsumeBytes(b) v, m := protowire.ConsumeBytes(b)
@ -294,7 +294,7 @@ func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
case genid.DescriptorProto_OneofDecl_field_number: case genid.DescriptorProto_OneofDecl_field_number:
rawOneofs = append(rawOneofs, v) rawOneofs = append(rawOneofs, v)
case genid.DescriptorProto_ReservedName_field_number: case genid.DescriptorProto_ReservedName_field_number:
md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v))) md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v)))
case genid.DescriptorProto_ReservedRange_field_number: case genid.DescriptorProto_ReservedRange_field_number:
md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v)) md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v))
case genid.DescriptorProto_ExtensionRange_field_number: case genid.DescriptorProto_ExtensionRange_field_number:
@ -326,7 +326,7 @@ func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) {
for i, b := range rawFields { for i, b := range rawFields {
fd := &md.L2.Fields.List[i] fd := &md.L2.Fields.List[i]
fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i) fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i)
if fd.L1.Cardinality == pref.Required { if fd.L1.Cardinality == protoreflect.Required {
md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number) md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number)
} }
} }
@ -359,7 +359,7 @@ func (md *Message) unmarshalOptions(b []byte) {
} }
} }
func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) { func unmarshalMessageReservedRange(b []byte) (r [2]protoreflect.FieldNumber) {
for len(b) > 0 { for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b) num, typ, n := protowire.ConsumeTag(b)
b = b[n:] b = b[n:]
@ -369,9 +369,9 @@ func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
b = b[m:] b = b[m:]
switch num { switch num {
case genid.DescriptorProto_ReservedRange_Start_field_number: case genid.DescriptorProto_ReservedRange_Start_field_number:
r[0] = pref.FieldNumber(v) r[0] = protoreflect.FieldNumber(v)
case genid.DescriptorProto_ReservedRange_End_field_number: case genid.DescriptorProto_ReservedRange_End_field_number:
r[1] = pref.FieldNumber(v) r[1] = protoreflect.FieldNumber(v)
} }
default: default:
m := protowire.ConsumeFieldValue(num, typ, b) m := protowire.ConsumeFieldValue(num, typ, b)
@ -381,7 +381,7 @@ func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) {
return r return r
} }
func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) { func unmarshalMessageExtensionRange(b []byte) (r [2]protoreflect.FieldNumber, rawOptions []byte) {
for len(b) > 0 { for len(b) > 0 {
num, typ, n := protowire.ConsumeTag(b) num, typ, n := protowire.ConsumeTag(b)
b = b[n:] b = b[n:]
@ -391,9 +391,9 @@ func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions
b = b[m:] b = b[m:]
switch num { switch num {
case genid.DescriptorProto_ExtensionRange_Start_field_number: case genid.DescriptorProto_ExtensionRange_Start_field_number:
r[0] = pref.FieldNumber(v) r[0] = protoreflect.FieldNumber(v)
case genid.DescriptorProto_ExtensionRange_End_field_number: case genid.DescriptorProto_ExtensionRange_End_field_number:
r[1] = pref.FieldNumber(v) r[1] = protoreflect.FieldNumber(v)
} }
case protowire.BytesType: case protowire.BytesType:
v, m := protowire.ConsumeBytes(b) v, m := protowire.ConsumeBytes(b)
@ -410,7 +410,7 @@ func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions
return r, rawOptions return r, rawOptions
} }
func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
fd.L0.ParentFile = pf fd.L0.ParentFile = pf
fd.L0.Parent = pd fd.L0.Parent = pd
fd.L0.Index = i fd.L0.Index = i
@ -426,11 +426,11 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des
b = b[m:] b = b[m:]
switch num { switch num {
case genid.FieldDescriptorProto_Number_field_number: case genid.FieldDescriptorProto_Number_field_number:
fd.L1.Number = pref.FieldNumber(v) fd.L1.Number = protoreflect.FieldNumber(v)
case genid.FieldDescriptorProto_Label_field_number: case genid.FieldDescriptorProto_Label_field_number:
fd.L1.Cardinality = pref.Cardinality(v) fd.L1.Cardinality = protoreflect.Cardinality(v)
case genid.FieldDescriptorProto_Type_field_number: case genid.FieldDescriptorProto_Type_field_number:
fd.L1.Kind = pref.Kind(v) fd.L1.Kind = protoreflect.Kind(v)
case genid.FieldDescriptorProto_OneofIndex_field_number: case genid.FieldDescriptorProto_OneofIndex_field_number:
// In Message.unmarshalFull, we allocate slices for both // In Message.unmarshalFull, we allocate slices for both
// the field and oneof descriptors before unmarshaling either // the field and oneof descriptors before unmarshaling either
@ -451,9 +451,9 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des
case genid.FieldDescriptorProto_Name_field_number: case genid.FieldDescriptorProto_Name_field_number:
fd.L0.FullName = appendFullName(sb, pd.FullName(), v) fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
case genid.FieldDescriptorProto_JsonName_field_number: case genid.FieldDescriptorProto_JsonName_field_number:
fd.L1.JSONName.Init(sb.MakeString(v)) fd.L1.StringName.InitJSON(sb.MakeString(v))
case genid.FieldDescriptorProto_DefaultValue_field_number: case genid.FieldDescriptorProto_DefaultValue_field_number:
fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages fd.L1.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
case genid.FieldDescriptorProto_TypeName_field_number: case genid.FieldDescriptorProto_TypeName_field_number:
rawTypeName = v rawTypeName = v
case genid.FieldDescriptorProto_Options_field_number: case genid.FieldDescriptorProto_Options_field_number:
@ -468,9 +468,9 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des
if rawTypeName != nil { if rawTypeName != nil {
name := makeFullName(sb, rawTypeName) name := makeFullName(sb, rawTypeName)
switch fd.L1.Kind { switch fd.L1.Kind {
case pref.EnumKind: case protoreflect.EnumKind:
fd.L1.Enum = PlaceholderEnum(name) fd.L1.Enum = PlaceholderEnum(name)
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
fd.L1.Message = PlaceholderMessage(name) fd.L1.Message = PlaceholderMessage(name)
} }
} }
@ -504,7 +504,7 @@ func (fd *Field) unmarshalOptions(b []byte) {
} }
} }
func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
od.L0.ParentFile = pf od.L0.ParentFile = pf
od.L0.Parent = pd od.L0.Parent = pd
od.L0.Index = i od.L0.Index = i
@ -551,9 +551,9 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
b = b[m:] b = b[m:]
switch num { switch num {
case genid.FieldDescriptorProto_JsonName_field_number: case genid.FieldDescriptorProto_JsonName_field_number:
xd.L2.JSONName.Init(sb.MakeString(v)) xd.L2.StringName.InitJSON(sb.MakeString(v))
case genid.FieldDescriptorProto_DefaultValue_field_number: case genid.FieldDescriptorProto_DefaultValue_field_number:
xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions xd.L2.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
case genid.FieldDescriptorProto_TypeName_field_number: case genid.FieldDescriptorProto_TypeName_field_number:
rawTypeName = v rawTypeName = v
case genid.FieldDescriptorProto_Options_field_number: case genid.FieldDescriptorProto_Options_field_number:
@ -568,9 +568,9 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
if rawTypeName != nil { if rawTypeName != nil {
name := makeFullName(sb, rawTypeName) name := makeFullName(sb, rawTypeName)
switch xd.L1.Kind { switch xd.L1.Kind {
case pref.EnumKind: case protoreflect.EnumKind:
xd.L2.Enum = PlaceholderEnum(name) xd.L2.Enum = PlaceholderEnum(name)
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
xd.L2.Message = PlaceholderMessage(name) xd.L2.Message = PlaceholderMessage(name)
} }
} }
@ -627,7 +627,7 @@ func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) {
sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions) sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions)
} }
func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) {
md.L0.ParentFile = pf md.L0.ParentFile = pf
md.L0.Parent = pd md.L0.Parent = pd
md.L0.Index = i md.L0.Index = i
@ -680,18 +680,18 @@ func appendOptions(dst, src []byte) []byte {
// //
// The type of message to unmarshal to is passed as a pointer since the // The type of message to unmarshal to is passed as a pointer since the
// vars in descopts may not yet be populated at the time this function is called. // vars in descopts may not yet be populated at the time this function is called.
func (db *Builder) optionsUnmarshaler(p *pref.ProtoMessage, b []byte) func() pref.ProtoMessage { func (db *Builder) optionsUnmarshaler(p *protoreflect.ProtoMessage, b []byte) func() protoreflect.ProtoMessage {
if b == nil { if b == nil {
return nil return nil
} }
var opts pref.ProtoMessage var opts protoreflect.ProtoMessage
var once sync.Once var once sync.Once
return func() pref.ProtoMessage { return func() protoreflect.ProtoMessage {
once.Do(func() { once.Do(func() {
if *p == nil { if *p == nil {
panic("Descriptor.Options called without importing the descriptor package") panic("Descriptor.Options called without importing the descriptor package")
} }
opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(pref.ProtoMessage) opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(protoreflect.ProtoMessage)
if err := (proto.UnmarshalOptions{ if err := (proto.UnmarshalOptions{
AllowPartial: true, AllowPartial: true,
Resolver: db.TypeResolver, Resolver: db.TypeResolver,

View File

@ -6,39 +6,41 @@ package filedesc
import ( import (
"fmt" "fmt"
"math"
"sort" "sort"
"sync" "sync"
"google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/descfmt" "google.golang.org/protobuf/internal/descfmt"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect"
) )
type FileImports []pref.FileImport type FileImports []protoreflect.FileImport
func (p *FileImports) Len() int { return len(*p) } func (p *FileImports) Len() int { return len(*p) }
func (p *FileImports) Get(i int) pref.FileImport { return (*p)[i] } func (p *FileImports) Get(i int) protoreflect.FileImport { return (*p)[i] }
func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {} func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
type Names struct { type Names struct {
List []pref.Name List []protoreflect.Name
once sync.Once once sync.Once
has map[pref.Name]int // protected by once has map[protoreflect.Name]int // protected by once
} }
func (p *Names) Len() int { return len(p.List) } func (p *Names) Len() int { return len(p.List) }
func (p *Names) Get(i int) pref.Name { return p.List[i] } func (p *Names) Get(i int) protoreflect.Name { return p.List[i] }
func (p *Names) Has(s pref.Name) bool { return p.lazyInit().has[s] > 0 } func (p *Names) Has(s protoreflect.Name) bool { return p.lazyInit().has[s] > 0 }
func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *Names) ProtoInternal(pragma.DoNotImplement) {} func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
func (p *Names) lazyInit() *Names { func (p *Names) lazyInit() *Names {
p.once.Do(func() { p.once.Do(func() {
if len(p.List) > 0 { if len(p.List) > 0 {
p.has = make(map[pref.Name]int, len(p.List)) p.has = make(map[protoreflect.Name]int, len(p.List))
for _, s := range p.List { for _, s := range p.List {
p.has[s] = p.has[s] + 1 p.has[s] = p.has[s] + 1
} }
@ -64,14 +66,14 @@ func (p *Names) CheckValid() error {
} }
type EnumRanges struct { type EnumRanges struct {
List [][2]pref.EnumNumber // start inclusive; end inclusive List [][2]protoreflect.EnumNumber // start inclusive; end inclusive
once sync.Once once sync.Once
sorted [][2]pref.EnumNumber // protected by once sorted [][2]protoreflect.EnumNumber // protected by once
} }
func (p *EnumRanges) Len() int { return len(p.List) } func (p *EnumRanges) Len() int { return len(p.List) }
func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] } func (p *EnumRanges) Get(i int) [2]protoreflect.EnumNumber { return p.List[i] }
func (p *EnumRanges) Has(n pref.EnumNumber) bool { func (p *EnumRanges) Has(n protoreflect.EnumNumber) bool {
for ls := p.lazyInit().sorted; len(ls) > 0; { for ls := p.lazyInit().sorted; len(ls) > 0; {
i := len(ls) / 2 i := len(ls) / 2
switch r := enumRange(ls[i]); { switch r := enumRange(ls[i]); {
@ -126,14 +128,14 @@ func (r enumRange) String() string {
} }
type FieldRanges struct { type FieldRanges struct {
List [][2]pref.FieldNumber // start inclusive; end exclusive List [][2]protoreflect.FieldNumber // start inclusive; end exclusive
once sync.Once once sync.Once
sorted [][2]pref.FieldNumber // protected by once sorted [][2]protoreflect.FieldNumber // protected by once
} }
func (p *FieldRanges) Len() int { return len(p.List) } func (p *FieldRanges) Len() int { return len(p.List) }
func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] } func (p *FieldRanges) Get(i int) [2]protoreflect.FieldNumber { return p.List[i] }
func (p *FieldRanges) Has(n pref.FieldNumber) bool { func (p *FieldRanges) Has(n protoreflect.FieldNumber) bool {
for ls := p.lazyInit().sorted; len(ls) > 0; { for ls := p.lazyInit().sorted; len(ls) > 0; {
i := len(ls) / 2 i := len(ls) / 2
switch r := fieldRange(ls[i]); { switch r := fieldRange(ls[i]); {
@ -218,17 +220,17 @@ func (r fieldRange) String() string {
} }
type FieldNumbers struct { type FieldNumbers struct {
List []pref.FieldNumber List []protoreflect.FieldNumber
once sync.Once once sync.Once
has map[pref.FieldNumber]struct{} // protected by once has map[protoreflect.FieldNumber]struct{} // protected by once
} }
func (p *FieldNumbers) Len() int { return len(p.List) } func (p *FieldNumbers) Len() int { return len(p.List) }
func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] } func (p *FieldNumbers) Get(i int) protoreflect.FieldNumber { return p.List[i] }
func (p *FieldNumbers) Has(n pref.FieldNumber) bool { func (p *FieldNumbers) Has(n protoreflect.FieldNumber) bool {
p.once.Do(func() { p.once.Do(func() {
if len(p.List) > 0 { if len(p.List) > 0 {
p.has = make(map[pref.FieldNumber]struct{}, len(p.List)) p.has = make(map[protoreflect.FieldNumber]struct{}, len(p.List))
for _, n := range p.List { for _, n := range p.List {
p.has[n] = struct{}{} p.has[n] = struct{}{}
} }
@ -241,31 +243,43 @@ func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList
func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {} func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
type OneofFields struct { type OneofFields struct {
List []pref.FieldDescriptor List []protoreflect.FieldDescriptor
once sync.Once once sync.Once
byName map[pref.Name]pref.FieldDescriptor // protected by once byName map[protoreflect.Name]protoreflect.FieldDescriptor // protected by once
byJSON map[string]pref.FieldDescriptor // protected by once byJSON map[string]protoreflect.FieldDescriptor // protected by once
byNum map[pref.FieldNumber]pref.FieldDescriptor // protected by once byText map[string]protoreflect.FieldDescriptor // protected by once
byNum map[protoreflect.FieldNumber]protoreflect.FieldDescriptor // protected by once
} }
func (p *OneofFields) Len() int { return len(p.List) } func (p *OneofFields) Len() int { return len(p.List) }
func (p *OneofFields) Get(i int) pref.FieldDescriptor { return p.List[i] } func (p *OneofFields) Get(i int) protoreflect.FieldDescriptor { return p.List[i] }
func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor { return p.lazyInit().byName[s] } func (p *OneofFields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor { return p.lazyInit().byJSON[s] } return p.lazyInit().byName[s]
func (p *OneofFields) ByNumber(n pref.FieldNumber) pref.FieldDescriptor { return p.lazyInit().byNum[n] } }
func (p *OneofFields) ByJSONName(s string) protoreflect.FieldDescriptor {
return p.lazyInit().byJSON[s]
}
func (p *OneofFields) ByTextName(s string) protoreflect.FieldDescriptor {
return p.lazyInit().byText[s]
}
func (p *OneofFields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
return p.lazyInit().byNum[n]
}
func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {} func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {}
func (p *OneofFields) lazyInit() *OneofFields { func (p *OneofFields) lazyInit() *OneofFields {
p.once.Do(func() { p.once.Do(func() {
if len(p.List) > 0 { if len(p.List) > 0 {
p.byName = make(map[pref.Name]pref.FieldDescriptor, len(p.List)) p.byName = make(map[protoreflect.Name]protoreflect.FieldDescriptor, len(p.List))
p.byJSON = make(map[string]pref.FieldDescriptor, len(p.List)) p.byJSON = make(map[string]protoreflect.FieldDescriptor, len(p.List))
p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List)) p.byText = make(map[string]protoreflect.FieldDescriptor, len(p.List))
p.byNum = make(map[protoreflect.FieldNumber]protoreflect.FieldDescriptor, len(p.List))
for _, f := range p.List { for _, f := range p.List {
// Field names and numbers are guaranteed to be unique. // Field names and numbers are guaranteed to be unique.
p.byName[f.Name()] = f p.byName[f.Name()] = f
p.byJSON[f.JSONName()] = f p.byJSON[f.JSONName()] = f
p.byText[f.TextName()] = f
p.byNum[f.Number()] = f p.byNum[f.Number()] = f
} }
} }
@ -274,9 +288,170 @@ func (p *OneofFields) lazyInit() *OneofFields {
} }
type SourceLocations struct { type SourceLocations struct {
List []pref.SourceLocation // List is a list of SourceLocations.
// The SourceLocation.Next field does not need to be populated
// as it will be lazily populated upon first need.
List []protoreflect.SourceLocation
// File is the parent file descriptor that these locations are relative to.
// If non-nil, ByDescriptor verifies that the provided descriptor
// is a child of this file descriptor.
File protoreflect.FileDescriptor
once sync.Once
byPath map[pathKey]int
} }
func (p *SourceLocations) Len() int { return len(p.List) } func (p *SourceLocations) Len() int { return len(p.List) }
func (p *SourceLocations) Get(i int) pref.SourceLocation { return p.List[i] } func (p *SourceLocations) Get(i int) protoreflect.SourceLocation { return p.lazyInit().List[i] }
func (p *SourceLocations) byKey(k pathKey) protoreflect.SourceLocation {
if i, ok := p.lazyInit().byPath[k]; ok {
return p.List[i]
}
return protoreflect.SourceLocation{}
}
func (p *SourceLocations) ByPath(path protoreflect.SourcePath) protoreflect.SourceLocation {
return p.byKey(newPathKey(path))
}
func (p *SourceLocations) ByDescriptor(desc protoreflect.Descriptor) protoreflect.SourceLocation {
if p.File != nil && desc != nil && p.File != desc.ParentFile() {
return protoreflect.SourceLocation{} // mismatching parent files
}
var pathArr [16]int32
path := pathArr[:0]
for {
switch desc.(type) {
case protoreflect.FileDescriptor:
// Reverse the path since it was constructed in reverse.
for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
path[i], path[j] = path[j], path[i]
}
return p.byKey(newPathKey(path))
case protoreflect.MessageDescriptor:
path = append(path, int32(desc.Index()))
desc = desc.Parent()
switch desc.(type) {
case protoreflect.FileDescriptor:
path = append(path, int32(genid.FileDescriptorProto_MessageType_field_number))
case protoreflect.MessageDescriptor:
path = append(path, int32(genid.DescriptorProto_NestedType_field_number))
default:
return protoreflect.SourceLocation{}
}
case protoreflect.FieldDescriptor:
isExtension := desc.(protoreflect.FieldDescriptor).IsExtension()
path = append(path, int32(desc.Index()))
desc = desc.Parent()
if isExtension {
switch desc.(type) {
case protoreflect.FileDescriptor:
path = append(path, int32(genid.FileDescriptorProto_Extension_field_number))
case protoreflect.MessageDescriptor:
path = append(path, int32(genid.DescriptorProto_Extension_field_number))
default:
return protoreflect.SourceLocation{}
}
} else {
switch desc.(type) {
case protoreflect.MessageDescriptor:
path = append(path, int32(genid.DescriptorProto_Field_field_number))
default:
return protoreflect.SourceLocation{}
}
}
case protoreflect.OneofDescriptor:
path = append(path, int32(desc.Index()))
desc = desc.Parent()
switch desc.(type) {
case protoreflect.MessageDescriptor:
path = append(path, int32(genid.DescriptorProto_OneofDecl_field_number))
default:
return protoreflect.SourceLocation{}
}
case protoreflect.EnumDescriptor:
path = append(path, int32(desc.Index()))
desc = desc.Parent()
switch desc.(type) {
case protoreflect.FileDescriptor:
path = append(path, int32(genid.FileDescriptorProto_EnumType_field_number))
case protoreflect.MessageDescriptor:
path = append(path, int32(genid.DescriptorProto_EnumType_field_number))
default:
return protoreflect.SourceLocation{}
}
case protoreflect.EnumValueDescriptor:
path = append(path, int32(desc.Index()))
desc = desc.Parent()
switch desc.(type) {
case protoreflect.EnumDescriptor:
path = append(path, int32(genid.EnumDescriptorProto_Value_field_number))
default:
return protoreflect.SourceLocation{}
}
case protoreflect.ServiceDescriptor:
path = append(path, int32(desc.Index()))
desc = desc.Parent()
switch desc.(type) {
case protoreflect.FileDescriptor:
path = append(path, int32(genid.FileDescriptorProto_Service_field_number))
default:
return protoreflect.SourceLocation{}
}
case protoreflect.MethodDescriptor:
path = append(path, int32(desc.Index()))
desc = desc.Parent()
switch desc.(type) {
case protoreflect.ServiceDescriptor:
path = append(path, int32(genid.ServiceDescriptorProto_Method_field_number))
default:
return protoreflect.SourceLocation{}
}
default:
return protoreflect.SourceLocation{}
}
}
}
func (p *SourceLocations) lazyInit() *SourceLocations {
p.once.Do(func() {
if len(p.List) > 0 {
// Collect all the indexes for a given path.
pathIdxs := make(map[pathKey][]int, len(p.List))
for i, l := range p.List {
k := newPathKey(l.Path)
pathIdxs[k] = append(pathIdxs[k], i)
}
// Update the next index for all locations.
p.byPath = make(map[pathKey]int, len(p.List))
for k, idxs := range pathIdxs {
for i := 0; i < len(idxs)-1; i++ {
p.List[idxs[i]].Next = idxs[i+1]
}
p.List[idxs[len(idxs)-1]].Next = 0
p.byPath[k] = idxs[0] // record the first location for this path
}
}
})
return p
}
func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {} func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}
// pathKey is a comparable representation of protoreflect.SourcePath.
type pathKey struct {
arr [16]uint8 // first n-1 path segments; last element is the length
str string // used if the path does not fit in arr
}
func newPathKey(p protoreflect.SourcePath) (k pathKey) {
if len(p) < len(k.arr) {
for i, ps := range p {
if ps < 0 || math.MaxUint8 <= ps {
return pathKey{str: p.String()}
}
k.arr[i] = uint8(ps)
}
k.arr[len(k.arr)-1] = uint8(len(p))
return k
}
return pathKey{str: p.String()}
}

View File

@ -142,6 +142,7 @@ type Fields struct {
once sync.Once once sync.Once
byName map[protoreflect.Name]*Field // protected by once byName map[protoreflect.Name]*Field // protected by once
byJSON map[string]*Field // protected by once byJSON map[string]*Field // protected by once
byText map[string]*Field // protected by once
byNum map[protoreflect.FieldNumber]*Field // protected by once byNum map[protoreflect.FieldNumber]*Field // protected by once
} }
@ -163,6 +164,12 @@ func (p *Fields) ByJSONName(s string) protoreflect.FieldDescriptor {
} }
return nil return nil
} }
func (p *Fields) ByTextName(s string) protoreflect.FieldDescriptor {
if d := p.lazyInit().byText[s]; d != nil {
return d
}
return nil
}
func (p *Fields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor { func (p *Fields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
if d := p.lazyInit().byNum[n]; d != nil { if d := p.lazyInit().byNum[n]; d != nil {
return d return d
@ -178,6 +185,7 @@ func (p *Fields) lazyInit() *Fields {
if len(p.List) > 0 { if len(p.List) > 0 {
p.byName = make(map[protoreflect.Name]*Field, len(p.List)) p.byName = make(map[protoreflect.Name]*Field, len(p.List))
p.byJSON = make(map[string]*Field, len(p.List)) p.byJSON = make(map[string]*Field, len(p.List))
p.byText = make(map[string]*Field, len(p.List))
p.byNum = make(map[protoreflect.FieldNumber]*Field, len(p.List)) p.byNum = make(map[protoreflect.FieldNumber]*Field, len(p.List))
for i := range p.List { for i := range p.List {
d := &p.List[i] d := &p.List[i]
@ -187,6 +195,9 @@ func (p *Fields) lazyInit() *Fields {
if _, ok := p.byJSON[d.JSONName()]; !ok { if _, ok := p.byJSON[d.JSONName()]; !ok {
p.byJSON[d.JSONName()] = d p.byJSON[d.JSONName()] = d
} }
if _, ok := p.byText[d.TextName()]; !ok {
p.byText[d.TextName()] = d
}
if _, ok := p.byNum[d.Number()]; !ok { if _, ok := p.byNum[d.Number()]; !ok {
p.byNum[d.Number()] = d p.byNum[d.Number()] = d
} }

View File

@ -7,7 +7,7 @@ package filedesc
import ( import (
"google.golang.org/protobuf/internal/descopts" "google.golang.org/protobuf/internal/descopts"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
var ( var (
@ -30,78 +30,80 @@ var (
// PlaceholderFile is a placeholder, representing only the file path. // PlaceholderFile is a placeholder, representing only the file path.
type PlaceholderFile string type PlaceholderFile string
func (f PlaceholderFile) ParentFile() pref.FileDescriptor { return f } func (f PlaceholderFile) ParentFile() protoreflect.FileDescriptor { return f }
func (f PlaceholderFile) Parent() pref.Descriptor { return nil } func (f PlaceholderFile) Parent() protoreflect.Descriptor { return nil }
func (f PlaceholderFile) Index() int { return 0 } func (f PlaceholderFile) Index() int { return 0 }
func (f PlaceholderFile) Syntax() pref.Syntax { return 0 } func (f PlaceholderFile) Syntax() protoreflect.Syntax { return 0 }
func (f PlaceholderFile) Name() pref.Name { return "" } func (f PlaceholderFile) Name() protoreflect.Name { return "" }
func (f PlaceholderFile) FullName() pref.FullName { return "" } func (f PlaceholderFile) FullName() protoreflect.FullName { return "" }
func (f PlaceholderFile) IsPlaceholder() bool { return true } func (f PlaceholderFile) IsPlaceholder() bool { return true }
func (f PlaceholderFile) Options() pref.ProtoMessage { return descopts.File } func (f PlaceholderFile) Options() protoreflect.ProtoMessage { return descopts.File }
func (f PlaceholderFile) Path() string { return string(f) } func (f PlaceholderFile) Path() string { return string(f) }
func (f PlaceholderFile) Package() pref.FullName { return "" } func (f PlaceholderFile) Package() protoreflect.FullName { return "" }
func (f PlaceholderFile) Imports() pref.FileImports { return emptyFiles } func (f PlaceholderFile) Imports() protoreflect.FileImports { return emptyFiles }
func (f PlaceholderFile) Messages() pref.MessageDescriptors { return emptyMessages } func (f PlaceholderFile) Messages() protoreflect.MessageDescriptors { return emptyMessages }
func (f PlaceholderFile) Enums() pref.EnumDescriptors { return emptyEnums } func (f PlaceholderFile) Enums() protoreflect.EnumDescriptors { return emptyEnums }
func (f PlaceholderFile) Extensions() pref.ExtensionDescriptors { return emptyExtensions } func (f PlaceholderFile) Extensions() protoreflect.ExtensionDescriptors { return emptyExtensions }
func (f PlaceholderFile) Services() pref.ServiceDescriptors { return emptyServices } func (f PlaceholderFile) Services() protoreflect.ServiceDescriptors { return emptyServices }
func (f PlaceholderFile) SourceLocations() pref.SourceLocations { return emptySourceLocations } func (f PlaceholderFile) SourceLocations() protoreflect.SourceLocations { return emptySourceLocations }
func (f PlaceholderFile) ProtoType(pref.FileDescriptor) { return } func (f PlaceholderFile) ProtoType(protoreflect.FileDescriptor) { return }
func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement) { return } func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement) { return }
// PlaceholderEnum is a placeholder, representing only the full name. // PlaceholderEnum is a placeholder, representing only the full name.
type PlaceholderEnum pref.FullName type PlaceholderEnum protoreflect.FullName
func (e PlaceholderEnum) ParentFile() pref.FileDescriptor { return nil } func (e PlaceholderEnum) ParentFile() protoreflect.FileDescriptor { return nil }
func (e PlaceholderEnum) Parent() pref.Descriptor { return nil } func (e PlaceholderEnum) Parent() protoreflect.Descriptor { return nil }
func (e PlaceholderEnum) Index() int { return 0 } func (e PlaceholderEnum) Index() int { return 0 }
func (e PlaceholderEnum) Syntax() pref.Syntax { return 0 } func (e PlaceholderEnum) Syntax() protoreflect.Syntax { return 0 }
func (e PlaceholderEnum) Name() pref.Name { return pref.FullName(e).Name() } func (e PlaceholderEnum) Name() protoreflect.Name { return protoreflect.FullName(e).Name() }
func (e PlaceholderEnum) FullName() pref.FullName { return pref.FullName(e) } func (e PlaceholderEnum) FullName() protoreflect.FullName { return protoreflect.FullName(e) }
func (e PlaceholderEnum) IsPlaceholder() bool { return true } func (e PlaceholderEnum) IsPlaceholder() bool { return true }
func (e PlaceholderEnum) Options() pref.ProtoMessage { return descopts.Enum } func (e PlaceholderEnum) Options() protoreflect.ProtoMessage { return descopts.Enum }
func (e PlaceholderEnum) Values() pref.EnumValueDescriptors { return emptyEnumValues } func (e PlaceholderEnum) Values() protoreflect.EnumValueDescriptors { return emptyEnumValues }
func (e PlaceholderEnum) ReservedNames() pref.Names { return emptyNames } func (e PlaceholderEnum) ReservedNames() protoreflect.Names { return emptyNames }
func (e PlaceholderEnum) ReservedRanges() pref.EnumRanges { return emptyEnumRanges } func (e PlaceholderEnum) ReservedRanges() protoreflect.EnumRanges { return emptyEnumRanges }
func (e PlaceholderEnum) ProtoType(pref.EnumDescriptor) { return } func (e PlaceholderEnum) ProtoType(protoreflect.EnumDescriptor) { return }
func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return } func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return }
// PlaceholderEnumValue is a placeholder, representing only the full name. // PlaceholderEnumValue is a placeholder, representing only the full name.
type PlaceholderEnumValue pref.FullName type PlaceholderEnumValue protoreflect.FullName
func (e PlaceholderEnumValue) ParentFile() pref.FileDescriptor { return nil } func (e PlaceholderEnumValue) ParentFile() protoreflect.FileDescriptor { return nil }
func (e PlaceholderEnumValue) Parent() pref.Descriptor { return nil } func (e PlaceholderEnumValue) Parent() protoreflect.Descriptor { return nil }
func (e PlaceholderEnumValue) Index() int { return 0 } func (e PlaceholderEnumValue) Index() int { return 0 }
func (e PlaceholderEnumValue) Syntax() pref.Syntax { return 0 } func (e PlaceholderEnumValue) Syntax() protoreflect.Syntax { return 0 }
func (e PlaceholderEnumValue) Name() pref.Name { return pref.FullName(e).Name() } func (e PlaceholderEnumValue) Name() protoreflect.Name { return protoreflect.FullName(e).Name() }
func (e PlaceholderEnumValue) FullName() pref.FullName { return pref.FullName(e) } func (e PlaceholderEnumValue) FullName() protoreflect.FullName { return protoreflect.FullName(e) }
func (e PlaceholderEnumValue) IsPlaceholder() bool { return true } func (e PlaceholderEnumValue) IsPlaceholder() bool { return true }
func (e PlaceholderEnumValue) Options() pref.ProtoMessage { return descopts.EnumValue } func (e PlaceholderEnumValue) Options() protoreflect.ProtoMessage { return descopts.EnumValue }
func (e PlaceholderEnumValue) Number() pref.EnumNumber { return 0 } func (e PlaceholderEnumValue) Number() protoreflect.EnumNumber { return 0 }
func (e PlaceholderEnumValue) ProtoType(pref.EnumValueDescriptor) { return } func (e PlaceholderEnumValue) ProtoType(protoreflect.EnumValueDescriptor) { return }
func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return } func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return }
// PlaceholderMessage is a placeholder, representing only the full name. // PlaceholderMessage is a placeholder, representing only the full name.
type PlaceholderMessage pref.FullName type PlaceholderMessage protoreflect.FullName
func (m PlaceholderMessage) ParentFile() pref.FileDescriptor { return nil } func (m PlaceholderMessage) ParentFile() protoreflect.FileDescriptor { return nil }
func (m PlaceholderMessage) Parent() pref.Descriptor { return nil } func (m PlaceholderMessage) Parent() protoreflect.Descriptor { return nil }
func (m PlaceholderMessage) Index() int { return 0 } func (m PlaceholderMessage) Index() int { return 0 }
func (m PlaceholderMessage) Syntax() pref.Syntax { return 0 } func (m PlaceholderMessage) Syntax() protoreflect.Syntax { return 0 }
func (m PlaceholderMessage) Name() pref.Name { return pref.FullName(m).Name() } func (m PlaceholderMessage) Name() protoreflect.Name { return protoreflect.FullName(m).Name() }
func (m PlaceholderMessage) FullName() pref.FullName { return pref.FullName(m) } func (m PlaceholderMessage) FullName() protoreflect.FullName { return protoreflect.FullName(m) }
func (m PlaceholderMessage) IsPlaceholder() bool { return true } func (m PlaceholderMessage) IsPlaceholder() bool { return true }
func (m PlaceholderMessage) Options() pref.ProtoMessage { return descopts.Message } func (m PlaceholderMessage) Options() protoreflect.ProtoMessage { return descopts.Message }
func (m PlaceholderMessage) IsMapEntry() bool { return false } func (m PlaceholderMessage) IsMapEntry() bool { return false }
func (m PlaceholderMessage) Fields() pref.FieldDescriptors { return emptyFields } func (m PlaceholderMessage) Fields() protoreflect.FieldDescriptors { return emptyFields }
func (m PlaceholderMessage) Oneofs() pref.OneofDescriptors { return emptyOneofs } func (m PlaceholderMessage) Oneofs() protoreflect.OneofDescriptors { return emptyOneofs }
func (m PlaceholderMessage) ReservedNames() pref.Names { return emptyNames } func (m PlaceholderMessage) ReservedNames() protoreflect.Names { return emptyNames }
func (m PlaceholderMessage) ReservedRanges() pref.FieldRanges { return emptyFieldRanges } func (m PlaceholderMessage) ReservedRanges() protoreflect.FieldRanges { return emptyFieldRanges }
func (m PlaceholderMessage) RequiredNumbers() pref.FieldNumbers { return emptyFieldNumbers } func (m PlaceholderMessage) RequiredNumbers() protoreflect.FieldNumbers { return emptyFieldNumbers }
func (m PlaceholderMessage) ExtensionRanges() pref.FieldRanges { return emptyFieldRanges } func (m PlaceholderMessage) ExtensionRanges() protoreflect.FieldRanges { return emptyFieldRanges }
func (m PlaceholderMessage) ExtensionRangeOptions(int) pref.ProtoMessage { panic("index out of range") } func (m PlaceholderMessage) ExtensionRangeOptions(int) protoreflect.ProtoMessage {
func (m PlaceholderMessage) Messages() pref.MessageDescriptors { return emptyMessages } panic("index out of range")
func (m PlaceholderMessage) Enums() pref.EnumDescriptors { return emptyEnums } }
func (m PlaceholderMessage) Extensions() pref.ExtensionDescriptors { return emptyExtensions } func (m PlaceholderMessage) Messages() protoreflect.MessageDescriptors { return emptyMessages }
func (m PlaceholderMessage) ProtoType(pref.MessageDescriptor) { return } func (m PlaceholderMessage) Enums() protoreflect.EnumDescriptors { return emptyEnums }
func (m PlaceholderMessage) Extensions() protoreflect.ExtensionDescriptors { return emptyExtensions }
func (m PlaceholderMessage) ProtoType(protoreflect.MessageDescriptor) { return }
func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement) { return } func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement) { return }

View File

@ -10,17 +10,16 @@ import (
"reflect" "reflect"
"google.golang.org/protobuf/internal/descopts" "google.golang.org/protobuf/internal/descopts"
fdesc "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
pimpl "google.golang.org/protobuf/internal/impl" pimpl "google.golang.org/protobuf/internal/impl"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
// Builder constructs type descriptors from a raw file descriptor // Builder constructs type descriptors from a raw file descriptor
// and associated Go types for each enum and message declaration. // and associated Go types for each enum and message declaration.
// //
// // # Flattened Ordering
// Flattened Ordering
// //
// The protobuf type system represents declarations as a tree. Certain nodes in // The protobuf type system represents declarations as a tree. Certain nodes in
// the tree require us to either associate it with a concrete Go type or to // the tree require us to either associate it with a concrete Go type or to
@ -52,7 +51,7 @@ import (
// that children themselves may have. // that children themselves may have.
type Builder struct { type Builder struct {
// File is the underlying file descriptor builder. // File is the underlying file descriptor builder.
File fdesc.Builder File filedesc.Builder
// GoTypes is a unique set of the Go types for all declarations and // GoTypes is a unique set of the Go types for all declarations and
// dependencies. Each type is represented as a zero value of the Go type. // dependencies. Each type is represented as a zero value of the Go type.
@ -108,22 +107,22 @@ type Builder struct {
// TypeRegistry is the registry to register each type descriptor. // TypeRegistry is the registry to register each type descriptor.
// If nil, it uses protoregistry.GlobalTypes. // If nil, it uses protoregistry.GlobalTypes.
TypeRegistry interface { TypeRegistry interface {
RegisterMessage(pref.MessageType) error RegisterMessage(protoreflect.MessageType) error
RegisterEnum(pref.EnumType) error RegisterEnum(protoreflect.EnumType) error
RegisterExtension(pref.ExtensionType) error RegisterExtension(protoreflect.ExtensionType) error
} }
} }
// Out is the output of the builder. // Out is the output of the builder.
type Out struct { type Out struct {
File pref.FileDescriptor File protoreflect.FileDescriptor
} }
func (tb Builder) Build() (out Out) { func (tb Builder) Build() (out Out) {
// Replace the resolver with one that resolves dependencies by index, // Replace the resolver with one that resolves dependencies by index,
// which is faster and more reliable than relying on the global registry. // which is faster and more reliable than relying on the global registry.
if tb.File.FileRegistry == nil { if tb.File.FileRegistry == nil {
tb.File.FileRegistry = preg.GlobalFiles tb.File.FileRegistry = protoregistry.GlobalFiles
} }
tb.File.FileRegistry = &resolverByIndex{ tb.File.FileRegistry = &resolverByIndex{
goTypes: tb.GoTypes, goTypes: tb.GoTypes,
@ -133,7 +132,7 @@ func (tb Builder) Build() (out Out) {
// Initialize registry if unpopulated. // Initialize registry if unpopulated.
if tb.TypeRegistry == nil { if tb.TypeRegistry == nil {
tb.TypeRegistry = preg.GlobalTypes tb.TypeRegistry = protoregistry.GlobalTypes
} }
fbOut := tb.File.Build() fbOut := tb.File.Build()
@ -183,23 +182,23 @@ func (tb Builder) Build() (out Out) {
for i := range fbOut.Messages { for i := range fbOut.Messages {
switch fbOut.Messages[i].Name() { switch fbOut.Messages[i].Name() {
case "FileOptions": case "FileOptions":
descopts.File = messageGoTypes[i].(pref.ProtoMessage) descopts.File = messageGoTypes[i].(protoreflect.ProtoMessage)
case "EnumOptions": case "EnumOptions":
descopts.Enum = messageGoTypes[i].(pref.ProtoMessage) descopts.Enum = messageGoTypes[i].(protoreflect.ProtoMessage)
case "EnumValueOptions": case "EnumValueOptions":
descopts.EnumValue = messageGoTypes[i].(pref.ProtoMessage) descopts.EnumValue = messageGoTypes[i].(protoreflect.ProtoMessage)
case "MessageOptions": case "MessageOptions":
descopts.Message = messageGoTypes[i].(pref.ProtoMessage) descopts.Message = messageGoTypes[i].(protoreflect.ProtoMessage)
case "FieldOptions": case "FieldOptions":
descopts.Field = messageGoTypes[i].(pref.ProtoMessage) descopts.Field = messageGoTypes[i].(protoreflect.ProtoMessage)
case "OneofOptions": case "OneofOptions":
descopts.Oneof = messageGoTypes[i].(pref.ProtoMessage) descopts.Oneof = messageGoTypes[i].(protoreflect.ProtoMessage)
case "ExtensionRangeOptions": case "ExtensionRangeOptions":
descopts.ExtensionRange = messageGoTypes[i].(pref.ProtoMessage) descopts.ExtensionRange = messageGoTypes[i].(protoreflect.ProtoMessage)
case "ServiceOptions": case "ServiceOptions":
descopts.Service = messageGoTypes[i].(pref.ProtoMessage) descopts.Service = messageGoTypes[i].(protoreflect.ProtoMessage)
case "MethodOptions": case "MethodOptions":
descopts.Method = messageGoTypes[i].(pref.ProtoMessage) descopts.Method = messageGoTypes[i].(protoreflect.ProtoMessage)
} }
} }
} }
@ -216,11 +215,11 @@ func (tb Builder) Build() (out Out) {
const listExtDeps = 2 const listExtDeps = 2
var goType reflect.Type var goType reflect.Type
switch fbOut.Extensions[i].L1.Kind { switch fbOut.Extensions[i].L1.Kind {
case pref.EnumKind: case protoreflect.EnumKind:
j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx) j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
goType = reflect.TypeOf(tb.GoTypes[j]) goType = reflect.TypeOf(tb.GoTypes[j])
depIdx++ depIdx++
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx) j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
goType = reflect.TypeOf(tb.GoTypes[j]) goType = reflect.TypeOf(tb.GoTypes[j])
depIdx++ depIdx++
@ -242,22 +241,22 @@ func (tb Builder) Build() (out Out) {
return out return out
} }
var goTypeForPBKind = map[pref.Kind]reflect.Type{ var goTypeForPBKind = map[protoreflect.Kind]reflect.Type{
pref.BoolKind: reflect.TypeOf(bool(false)), protoreflect.BoolKind: reflect.TypeOf(bool(false)),
pref.Int32Kind: reflect.TypeOf(int32(0)), protoreflect.Int32Kind: reflect.TypeOf(int32(0)),
pref.Sint32Kind: reflect.TypeOf(int32(0)), protoreflect.Sint32Kind: reflect.TypeOf(int32(0)),
pref.Sfixed32Kind: reflect.TypeOf(int32(0)), protoreflect.Sfixed32Kind: reflect.TypeOf(int32(0)),
pref.Int64Kind: reflect.TypeOf(int64(0)), protoreflect.Int64Kind: reflect.TypeOf(int64(0)),
pref.Sint64Kind: reflect.TypeOf(int64(0)), protoreflect.Sint64Kind: reflect.TypeOf(int64(0)),
pref.Sfixed64Kind: reflect.TypeOf(int64(0)), protoreflect.Sfixed64Kind: reflect.TypeOf(int64(0)),
pref.Uint32Kind: reflect.TypeOf(uint32(0)), protoreflect.Uint32Kind: reflect.TypeOf(uint32(0)),
pref.Fixed32Kind: reflect.TypeOf(uint32(0)), protoreflect.Fixed32Kind: reflect.TypeOf(uint32(0)),
pref.Uint64Kind: reflect.TypeOf(uint64(0)), protoreflect.Uint64Kind: reflect.TypeOf(uint64(0)),
pref.Fixed64Kind: reflect.TypeOf(uint64(0)), protoreflect.Fixed64Kind: reflect.TypeOf(uint64(0)),
pref.FloatKind: reflect.TypeOf(float32(0)), protoreflect.FloatKind: reflect.TypeOf(float32(0)),
pref.DoubleKind: reflect.TypeOf(float64(0)), protoreflect.DoubleKind: reflect.TypeOf(float64(0)),
pref.StringKind: reflect.TypeOf(string("")), protoreflect.StringKind: reflect.TypeOf(string("")),
pref.BytesKind: reflect.TypeOf([]byte(nil)), protoreflect.BytesKind: reflect.TypeOf([]byte(nil)),
} }
type depIdxs []int32 type depIdxs []int32
@ -274,13 +273,13 @@ type (
fileRegistry fileRegistry
} }
fileRegistry interface { fileRegistry interface {
FindFileByPath(string) (pref.FileDescriptor, error) FindFileByPath(string) (protoreflect.FileDescriptor, error)
FindDescriptorByName(pref.FullName) (pref.Descriptor, error) FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
RegisterFile(pref.FileDescriptor) error RegisterFile(protoreflect.FileDescriptor) error
} }
) )
func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.EnumDescriptor { func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []filedesc.Enum, ms []filedesc.Message) protoreflect.EnumDescriptor {
if depIdx := int(r.depIdxs.Get(i, j)); int(depIdx) < len(es)+len(ms) { if depIdx := int(r.depIdxs.Get(i, j)); int(depIdx) < len(es)+len(ms) {
return &es[depIdx] return &es[depIdx]
} else { } else {
@ -288,7 +287,7 @@ func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []fdesc.Enum, ms []fdes
} }
} }
func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.MessageDescriptor { func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []filedesc.Enum, ms []filedesc.Message) protoreflect.MessageDescriptor {
if depIdx := int(r.depIdxs.Get(i, j)); depIdx < len(es)+len(ms) { if depIdx := int(r.depIdxs.Get(i, j)); depIdx < len(es)+len(ms) {
return &ms[depIdx-len(es)] return &ms[depIdx-len(es)]
} else { } else {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !protolegacy
// +build !protolegacy // +build !protolegacy
package flags package flags

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build protolegacy
// +build protolegacy // +build protolegacy
package flags package flags

View File

@ -12,8 +12,8 @@ import (
"google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/encoding/prototext"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
// Export is a zero-length named type that exists only to export a set of // Export is a zero-length named type that exists only to export a set of
@ -32,11 +32,11 @@ type enum = interface{}
// EnumOf returns the protoreflect.Enum interface over e. // EnumOf returns the protoreflect.Enum interface over e.
// It returns nil if e is nil. // It returns nil if e is nil.
func (Export) EnumOf(e enum) pref.Enum { func (Export) EnumOf(e enum) protoreflect.Enum {
switch e := e.(type) { switch e := e.(type) {
case nil: case nil:
return nil return nil
case pref.Enum: case protoreflect.Enum:
return e return e
default: default:
return legacyWrapEnum(reflect.ValueOf(e)) return legacyWrapEnum(reflect.ValueOf(e))
@ -45,11 +45,11 @@ func (Export) EnumOf(e enum) pref.Enum {
// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e. // EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
// It returns nil if e is nil. // It returns nil if e is nil.
func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor { func (Export) EnumDescriptorOf(e enum) protoreflect.EnumDescriptor {
switch e := e.(type) { switch e := e.(type) {
case nil: case nil:
return nil return nil
case pref.Enum: case protoreflect.Enum:
return e.Descriptor() return e.Descriptor()
default: default:
return LegacyLoadEnumDesc(reflect.TypeOf(e)) return LegacyLoadEnumDesc(reflect.TypeOf(e))
@ -58,11 +58,11 @@ func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
// EnumTypeOf returns the protoreflect.EnumType for e. // EnumTypeOf returns the protoreflect.EnumType for e.
// It returns nil if e is nil. // It returns nil if e is nil.
func (Export) EnumTypeOf(e enum) pref.EnumType { func (Export) EnumTypeOf(e enum) protoreflect.EnumType {
switch e := e.(type) { switch e := e.(type) {
case nil: case nil:
return nil return nil
case pref.Enum: case protoreflect.Enum:
return e.Type() return e.Type()
default: default:
return legacyLoadEnumType(reflect.TypeOf(e)) return legacyLoadEnumType(reflect.TypeOf(e))
@ -71,7 +71,7 @@ func (Export) EnumTypeOf(e enum) pref.EnumType {
// EnumStringOf returns the enum value as a string, either as the name if // EnumStringOf returns the enum value as a string, either as the name if
// the number is resolvable, or the number formatted as a string. // the number is resolvable, or the number formatted as a string.
func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string { func (Export) EnumStringOf(ed protoreflect.EnumDescriptor, n protoreflect.EnumNumber) string {
ev := ed.Values().ByNumber(n) ev := ed.Values().ByNumber(n)
if ev != nil { if ev != nil {
return string(ev.Name()) return string(ev.Name())
@ -84,7 +84,7 @@ func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
type message = interface{} type message = interface{}
// legacyMessageWrapper wraps a v2 message as a v1 message. // legacyMessageWrapper wraps a v2 message as a v1 message.
type legacyMessageWrapper struct{ m pref.ProtoMessage } type legacyMessageWrapper struct{ m protoreflect.ProtoMessage }
func (m legacyMessageWrapper) Reset() { proto.Reset(m.m) } func (m legacyMessageWrapper) Reset() { proto.Reset(m.m) }
func (m legacyMessageWrapper) String() string { return Export{}.MessageStringOf(m.m) } func (m legacyMessageWrapper) String() string { return Export{}.MessageStringOf(m.m) }
@ -92,30 +92,30 @@ func (m legacyMessageWrapper) ProtoMessage() {}
// ProtoMessageV1Of converts either a v1 or v2 message to a v1 message. // ProtoMessageV1Of converts either a v1 or v2 message to a v1 message.
// It returns nil if m is nil. // It returns nil if m is nil.
func (Export) ProtoMessageV1Of(m message) piface.MessageV1 { func (Export) ProtoMessageV1Of(m message) protoiface.MessageV1 {
switch mv := m.(type) { switch mv := m.(type) {
case nil: case nil:
return nil return nil
case piface.MessageV1: case protoiface.MessageV1:
return mv return mv
case unwrapper: case unwrapper:
return Export{}.ProtoMessageV1Of(mv.protoUnwrap()) return Export{}.ProtoMessageV1Of(mv.protoUnwrap())
case pref.ProtoMessage: case protoreflect.ProtoMessage:
return legacyMessageWrapper{mv} return legacyMessageWrapper{mv}
default: default:
panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m)) panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
} }
} }
func (Export) protoMessageV2Of(m message) pref.ProtoMessage { func (Export) protoMessageV2Of(m message) protoreflect.ProtoMessage {
switch mv := m.(type) { switch mv := m.(type) {
case nil: case nil:
return nil return nil
case pref.ProtoMessage: case protoreflect.ProtoMessage:
return mv return mv
case legacyMessageWrapper: case legacyMessageWrapper:
return mv.m return mv.m
case piface.MessageV1: case protoiface.MessageV1:
return nil return nil
default: default:
panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m)) panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
@ -124,7 +124,7 @@ func (Export) protoMessageV2Of(m message) pref.ProtoMessage {
// ProtoMessageV2Of converts either a v1 or v2 message to a v2 message. // ProtoMessageV2Of converts either a v1 or v2 message to a v2 message.
// It returns nil if m is nil. // It returns nil if m is nil.
func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage { func (Export) ProtoMessageV2Of(m message) protoreflect.ProtoMessage {
if m == nil { if m == nil {
return nil return nil
} }
@ -136,7 +136,7 @@ func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage {
// MessageOf returns the protoreflect.Message interface over m. // MessageOf returns the protoreflect.Message interface over m.
// It returns nil if m is nil. // It returns nil if m is nil.
func (Export) MessageOf(m message) pref.Message { func (Export) MessageOf(m message) protoreflect.Message {
if m == nil { if m == nil {
return nil return nil
} }
@ -148,7 +148,7 @@ func (Export) MessageOf(m message) pref.Message {
// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m. // MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
// It returns nil if m is nil. // It returns nil if m is nil.
func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor { func (Export) MessageDescriptorOf(m message) protoreflect.MessageDescriptor {
if m == nil { if m == nil {
return nil return nil
} }
@ -160,18 +160,18 @@ func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
// MessageTypeOf returns the protoreflect.MessageType for m. // MessageTypeOf returns the protoreflect.MessageType for m.
// It returns nil if m is nil. // It returns nil if m is nil.
func (Export) MessageTypeOf(m message) pref.MessageType { func (Export) MessageTypeOf(m message) protoreflect.MessageType {
if m == nil { if m == nil {
return nil return nil
} }
if mv := (Export{}).protoMessageV2Of(m); mv != nil { if mv := (Export{}).protoMessageV2Of(m); mv != nil {
return mv.ProtoReflect().Type() return mv.ProtoReflect().Type()
} }
return legacyLoadMessageInfo(reflect.TypeOf(m), "") return legacyLoadMessageType(reflect.TypeOf(m), "")
} }
// MessageStringOf returns the message value as a string, // MessageStringOf returns the message value as a string,
// which is the message serialized in the protobuf text format. // which is the message serialized in the protobuf text format.
func (Export) MessageStringOf(m pref.ProtoMessage) string { func (Export) MessageStringOf(m protoreflect.ProtoMessage) string {
return prototext.MarshalOptions{Multiline: false}.Format(m) return prototext.MarshalOptions{Multiline: false}.Format(m)
} }

View File

@ -8,18 +8,18 @@ import (
"sync" "sync"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
func (mi *MessageInfo) checkInitialized(in piface.CheckInitializedInput) (piface.CheckInitializedOutput, error) { func (mi *MessageInfo) checkInitialized(in protoiface.CheckInitializedInput) (protoiface.CheckInitializedOutput, error) {
var p pointer var p pointer
if ms, ok := in.Message.(*messageState); ok { if ms, ok := in.Message.(*messageState); ok {
p = ms.pointer() p = ms.pointer()
} else { } else {
p = in.Message.(*messageReflectWrapper).pointer() p = in.Message.(*messageReflectWrapper).pointer()
} }
return piface.CheckInitializedOutput{}, mi.checkInitializedPointer(p) return protoiface.CheckInitializedOutput{}, mi.checkInitializedPointer(p)
} }
func (mi *MessageInfo) checkInitializedPointer(p pointer) error { func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
@ -90,7 +90,7 @@ var (
// needsInitCheck reports whether a message needs to be checked for partial initialization. // needsInitCheck reports whether a message needs to be checked for partial initialization.
// //
// It returns true if the message transitively includes any required or extension fields. // It returns true if the message transitively includes any required or extension fields.
func needsInitCheck(md pref.MessageDescriptor) bool { func needsInitCheck(md protoreflect.MessageDescriptor) bool {
if v, ok := needsInitCheckMap.Load(md); ok { if v, ok := needsInitCheckMap.Load(md); ok {
if has, ok := v.(bool); ok { if has, ok := v.(bool); ok {
return has return has
@ -101,7 +101,7 @@ func needsInitCheck(md pref.MessageDescriptor) bool {
return needsInitCheckLocked(md) return needsInitCheckLocked(md)
} }
func needsInitCheckLocked(md pref.MessageDescriptor) (has bool) { func needsInitCheckLocked(md protoreflect.MessageDescriptor) (has bool) {
if v, ok := needsInitCheckMap.Load(md); ok { if v, ok := needsInitCheckMap.Load(md); ok {
// If has is true, we've previously determined that this message // If has is true, we've previously determined that this message
// needs init checks. // needs init checks.

View File

@ -10,7 +10,7 @@ import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type extensionFieldInfo struct { type extensionFieldInfo struct {
@ -23,7 +23,7 @@ type extensionFieldInfo struct {
var legacyExtensionFieldInfoCache sync.Map // map[protoreflect.ExtensionType]*extensionFieldInfo var legacyExtensionFieldInfoCache sync.Map // map[protoreflect.ExtensionType]*extensionFieldInfo
func getExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { func getExtensionFieldInfo(xt protoreflect.ExtensionType) *extensionFieldInfo {
if xi, ok := xt.(*ExtensionInfo); ok { if xi, ok := xt.(*ExtensionInfo); ok {
xi.lazyInit() xi.lazyInit()
return xi.info return xi.info
@ -32,7 +32,7 @@ func getExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
} }
// legacyLoadExtensionFieldInfo dynamically loads a *ExtensionInfo for xt. // legacyLoadExtensionFieldInfo dynamically loads a *ExtensionInfo for xt.
func legacyLoadExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { func legacyLoadExtensionFieldInfo(xt protoreflect.ExtensionType) *extensionFieldInfo {
if xi, ok := legacyExtensionFieldInfoCache.Load(xt); ok { if xi, ok := legacyExtensionFieldInfoCache.Load(xt); ok {
return xi.(*extensionFieldInfo) return xi.(*extensionFieldInfo)
} }
@ -43,7 +43,7 @@ func legacyLoadExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
return e return e
} }
func makeExtensionFieldInfo(xd pref.ExtensionDescriptor) *extensionFieldInfo { func makeExtensionFieldInfo(xd protoreflect.ExtensionDescriptor) *extensionFieldInfo {
var wiretag uint64 var wiretag uint64
if !xd.IsPacked() { if !xd.IsPacked() {
wiretag = protowire.EncodeTag(xd.Number(), wireTypes[xd.Kind()]) wiretag = protowire.EncodeTag(xd.Number(), wireTypes[xd.Kind()])
@ -59,10 +59,10 @@ func makeExtensionFieldInfo(xd pref.ExtensionDescriptor) *extensionFieldInfo {
// This is true for composite types, where we pass in a message, list, or map to fill in, // This is true for composite types, where we pass in a message, list, or map to fill in,
// and for enums, where we pass in a prototype value to specify the concrete enum type. // and for enums, where we pass in a prototype value to specify the concrete enum type.
switch xd.Kind() { switch xd.Kind() {
case pref.MessageKind, pref.GroupKind, pref.EnumKind: case protoreflect.MessageKind, protoreflect.GroupKind, protoreflect.EnumKind:
e.unmarshalNeedsValue = true e.unmarshalNeedsValue = true
default: default:
if xd.Cardinality() == pref.Repeated { if xd.Cardinality() == protoreflect.Repeated {
e.unmarshalNeedsValue = true e.unmarshalNeedsValue = true
} }
} }
@ -73,21 +73,21 @@ type lazyExtensionValue struct {
atomicOnce uint32 // atomically set if value is valid atomicOnce uint32 // atomically set if value is valid
mu sync.Mutex mu sync.Mutex
xi *extensionFieldInfo xi *extensionFieldInfo
value pref.Value value protoreflect.Value
b []byte b []byte
fn func() pref.Value fn func() protoreflect.Value
} }
type ExtensionField struct { type ExtensionField struct {
typ pref.ExtensionType typ protoreflect.ExtensionType
// value is either the value of GetValue, // value is either the value of GetValue,
// or a *lazyExtensionValue that then returns the value of GetValue. // or a *lazyExtensionValue that then returns the value of GetValue.
value pref.Value value protoreflect.Value
lazy *lazyExtensionValue lazy *lazyExtensionValue
} }
func (f *ExtensionField) appendLazyBytes(xt pref.ExtensionType, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, b []byte) { func (f *ExtensionField) appendLazyBytes(xt protoreflect.ExtensionType, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, b []byte) {
if f.lazy == nil { if f.lazy == nil {
f.lazy = &lazyExtensionValue{xi: xi} f.lazy = &lazyExtensionValue{xi: xi}
} }
@ -97,7 +97,7 @@ func (f *ExtensionField) appendLazyBytes(xt pref.ExtensionType, xi *extensionFie
f.lazy.b = append(f.lazy.b, b...) f.lazy.b = append(f.lazy.b, b...)
} }
func (f *ExtensionField) canLazy(xt pref.ExtensionType) bool { func (f *ExtensionField) canLazy(xt protoreflect.ExtensionType) bool {
if f.typ == nil { if f.typ == nil {
return true return true
} }
@ -154,7 +154,7 @@ func (f *ExtensionField) lazyInit() {
// Set sets the type and value of the extension field. // Set sets the type and value of the extension field.
// This must not be called concurrently. // This must not be called concurrently.
func (f *ExtensionField) Set(t pref.ExtensionType, v pref.Value) { func (f *ExtensionField) Set(t protoreflect.ExtensionType, v protoreflect.Value) {
f.typ = t f.typ = t
f.value = v f.value = v
f.lazy = nil f.lazy = nil
@ -162,14 +162,14 @@ func (f *ExtensionField) Set(t pref.ExtensionType, v pref.Value) {
// SetLazy sets the type and a value that is to be lazily evaluated upon first use. // SetLazy sets the type and a value that is to be lazily evaluated upon first use.
// This must not be called concurrently. // This must not be called concurrently.
func (f *ExtensionField) SetLazy(t pref.ExtensionType, fn func() pref.Value) { func (f *ExtensionField) SetLazy(t protoreflect.ExtensionType, fn func() protoreflect.Value) {
f.typ = t f.typ = t
f.lazy = &lazyExtensionValue{fn: fn} f.lazy = &lazyExtensionValue{fn: fn}
} }
// Value returns the value of the extension field. // Value returns the value of the extension field.
// This may be called concurrently. // This may be called concurrently.
func (f *ExtensionField) Value() pref.Value { func (f *ExtensionField) Value() protoreflect.Value {
if f.lazy != nil { if f.lazy != nil {
if atomic.LoadUint32(&f.lazy.atomicOnce) == 0 { if atomic.LoadUint32(&f.lazy.atomicOnce) == 0 {
f.lazyInit() f.lazyInit()
@ -181,7 +181,7 @@ func (f *ExtensionField) Value() pref.Value {
// Type returns the type of the extension field. // Type returns the type of the extension field.
// This may be called concurrently. // This may be called concurrently.
func (f ExtensionField) Type() pref.ExtensionType { func (f ExtensionField) Type() protoreflect.ExtensionType {
return f.typ return f.typ
} }
@ -193,7 +193,7 @@ func (f ExtensionField) IsSet() bool {
// IsLazy reports whether a field is lazily encoded. // IsLazy reports whether a field is lazily encoded.
// It is exported for testing. // It is exported for testing.
func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool { func IsLazy(m protoreflect.Message, fd protoreflect.FieldDescriptor) bool {
var mi *MessageInfo var mi *MessageInfo
var p pointer var p pointer
switch m := m.(type) { switch m := m.(type) {
@ -206,7 +206,7 @@ func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool {
default: default:
return false return false
} }
xd, ok := fd.(pref.ExtensionTypeDescriptor) xd, ok := fd.(protoreflect.ExtensionTypeDescriptor)
if !ok { if !ok {
return false return false
} }

View File

@ -10,16 +10,18 @@ import (
"sync" "sync"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
type errInvalidUTF8 struct{} type errInvalidUTF8 struct{}
func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" } func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
func (errInvalidUTF8) InvalidUTF8() bool { return true } func (errInvalidUTF8) InvalidUTF8() bool { return true }
func (errInvalidUTF8) Unwrap() error { return errors.Error }
// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof. // initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
// //
@ -28,7 +30,7 @@ func (errInvalidUTF8) InvalidUTF8() bool { return true }
// to the appropriate field-specific function as necessary. // to the appropriate field-specific function as necessary.
// //
// The unmarshal function is set on each field individually as usual. // The unmarshal function is set on each field individually as usual.
func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) { func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si structInfo) {
fs := si.oneofsByName[od.Name()] fs := si.oneofsByName[od.Name()]
ft := fs.Type ft := fs.Type
oneofFields := make(map[reflect.Type]*coderFieldInfo) oneofFields := make(map[reflect.Type]*coderFieldInfo)
@ -116,13 +118,13 @@ func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structIn
} }
} }
func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs { func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs {
var once sync.Once var once sync.Once
var messageType pref.MessageType var messageType protoreflect.MessageType
lazyInit := func() { lazyInit := func() {
once.Do(func() { once.Do(func() {
messageName := fd.Message().FullName() messageName := fd.Message().FullName()
messageType, _ = preg.GlobalTypes.FindMessageByName(messageName) messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
}) })
} }
@ -188,7 +190,7 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
} }
} }
func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
if mi := getMessageInfo(ft); mi != nil { if mi := getMessageInfo(ft); mi != nil {
funcs := pointerCoderFuncs{ funcs := pointerCoderFuncs{
size: sizeMessageInfo, size: sizeMessageInfo,
@ -242,7 +244,7 @@ func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldI
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
if p.Elem().IsNil() { if p.Elem().IsNil() {
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))) p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
@ -276,9 +278,9 @@ func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarsh
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
Buf: v, Buf: v,
Message: m.ProtoReflect(), Message: m.ProtoReflect(),
}) })
@ -286,27 +288,27 @@ func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarsh
return out, err return out, err
} }
out.n = n out.n = n
out.initialized = o.Flags&piface.UnmarshalInitialized != 0 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
return out, nil return out, nil
} }
func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int { func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
m := v.Message().Interface() m := v.Message().Interface()
return sizeMessage(m, tagsize, opts) return sizeMessage(m, tagsize, opts)
} }
func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { func appendMessageValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
m := v.Message().Interface() m := v.Message().Interface()
return appendMessage(b, m, wiretag, opts) return appendMessage(b, m, wiretag, opts)
} }
func consumeMessageValue(b []byte, v pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) { func consumeMessageValue(b []byte, v protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
m := v.Message().Interface() m := v.Message().Interface()
out, err := consumeMessage(b, m, wtyp, opts) out, err := consumeMessage(b, m, wtyp, opts)
return v, out, err return v, out, err
} }
func isInitMessageValue(v pref.Value) error { func isInitMessageValue(v protoreflect.Value) error {
m := v.Message().Interface() m := v.Message().Interface()
return proto.CheckInitialized(m) return proto.CheckInitialized(m)
} }
@ -319,17 +321,17 @@ var coderMessageValue = valueCoderFuncs{
merge: mergeMessageValue, merge: mergeMessageValue,
} }
func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int { func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
m := v.Message().Interface() m := v.Message().Interface()
return sizeGroup(m, tagsize, opts) return sizeGroup(m, tagsize, opts)
} }
func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { func appendGroupValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
m := v.Message().Interface() m := v.Message().Interface()
return appendGroup(b, m, wiretag, opts) return appendGroup(b, m, wiretag, opts)
} }
func consumeGroupValue(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) { func consumeGroupValue(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
m := v.Message().Interface() m := v.Message().Interface()
out, err := consumeGroup(b, m, num, wtyp, opts) out, err := consumeGroup(b, m, num, wtyp, opts)
return v, out, err return v, out, err
@ -343,7 +345,7 @@ var coderGroupValue = valueCoderFuncs{
merge: mergeMessageValue, merge: mergeMessageValue,
} }
func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
num := fd.Number() num := fd.Number()
if mi := getMessageInfo(ft); mi != nil { if mi := getMessageInfo(ft); mi != nil {
funcs := pointerCoderFuncs{ funcs := pointerCoderFuncs{
@ -420,9 +422,9 @@ func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowir
} }
b, n := protowire.ConsumeGroup(num, b) b, n := protowire.ConsumeGroup(num, b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
Buf: b, Buf: b,
Message: m.ProtoReflect(), Message: m.ProtoReflect(),
}) })
@ -430,11 +432,11 @@ func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowir
return out, err return out, err
} }
out.n = n out.n = n
out.initialized = o.Flags&piface.UnmarshalInitialized != 0 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
return out, nil return out, nil
} }
func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { func makeMessageSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
if mi := getMessageInfo(ft); mi != nil { if mi := getMessageInfo(ft); mi != nil {
funcs := pointerCoderFuncs{ funcs := pointerCoderFuncs{
size: sizeMessageSliceInfo, size: sizeMessageSliceInfo,
@ -494,7 +496,7 @@ func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderF
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
m := reflect.New(f.mi.GoReflectType.Elem()).Interface() m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
mp := pointerOfIface(m) mp := pointerOfIface(m)
@ -550,10 +552,10 @@ func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowir
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
mp := reflect.New(goType.Elem()) mp := reflect.New(goType.Elem())
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
Buf: v, Buf: v,
Message: asMessage(mp).ProtoReflect(), Message: asMessage(mp).ProtoReflect(),
}) })
@ -562,7 +564,7 @@ func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowir
} }
p.AppendPointerSlice(pointerOfValue(mp)) p.AppendPointerSlice(pointerOfValue(mp))
out.n = n out.n = n
out.initialized = o.Flags&piface.UnmarshalInitialized != 0 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
return out, nil return out, nil
} }
@ -579,7 +581,7 @@ func isInitMessageSlice(p pointer, goType reflect.Type) error {
// Slices of messages // Slices of messages
func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int { func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
list := listv.List() list := listv.List()
n := 0 n := 0
for i, llen := 0, list.Len(); i < llen; i++ { for i, llen := 0, list.Len(); i < llen; i++ {
@ -589,7 +591,7 @@ func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) i
return n return n
} }
func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
list := listv.List() list := listv.List()
mopts := opts.Options() mopts := opts.Options()
for i, llen := 0, list.Len(); i < llen; i++ { for i, llen := 0, list.Len(); i < llen; i++ {
@ -606,30 +608,30 @@ func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts ma
return b, nil return b, nil
} }
func consumeMessageSliceValue(b []byte, listv pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) { func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
list := listv.List() list := listv.List()
if wtyp != protowire.BytesType { if wtyp != protowire.BytesType {
return pref.Value{}, out, errUnknown return protoreflect.Value{}, out, errUnknown
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return pref.Value{}, out, protowire.ParseError(n) return protoreflect.Value{}, out, errDecode
} }
m := list.NewElement() m := list.NewElement()
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
Buf: v, Buf: v,
Message: m.Message(), Message: m.Message(),
}) })
if err != nil { if err != nil {
return pref.Value{}, out, err return protoreflect.Value{}, out, err
} }
list.Append(m) list.Append(m)
out.n = n out.n = n
out.initialized = o.Flags&piface.UnmarshalInitialized != 0 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
return listv, out, nil return listv, out, nil
} }
func isInitMessageSliceValue(listv pref.Value) error { func isInitMessageSliceValue(listv protoreflect.Value) error {
list := listv.List() list := listv.List()
for i, llen := 0, list.Len(); i < llen; i++ { for i, llen := 0, list.Len(); i < llen; i++ {
m := list.Get(i).Message().Interface() m := list.Get(i).Message().Interface()
@ -648,7 +650,7 @@ var coderMessageSliceValue = valueCoderFuncs{
merge: mergeMessageListValue, merge: mergeMessageListValue,
} }
func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int { func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
list := listv.List() list := listv.List()
n := 0 n := 0
for i, llen := 0, list.Len(); i < llen; i++ { for i, llen := 0, list.Len(); i < llen; i++ {
@ -658,7 +660,7 @@ func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int
return n return n
} }
func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
list := listv.List() list := listv.List()
mopts := opts.Options() mopts := opts.Options()
for i, llen := 0, list.Len(); i < llen; i++ { for i, llen := 0, list.Len(); i < llen; i++ {
@ -674,26 +676,26 @@ func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts mars
return b, nil return b, nil
} }
func consumeGroupSliceValue(b []byte, listv pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) { func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
list := listv.List() list := listv.List()
if wtyp != protowire.StartGroupType { if wtyp != protowire.StartGroupType {
return pref.Value{}, out, errUnknown return protoreflect.Value{}, out, errUnknown
} }
b, n := protowire.ConsumeGroup(num, b) b, n := protowire.ConsumeGroup(num, b)
if n < 0 { if n < 0 {
return pref.Value{}, out, protowire.ParseError(n) return protoreflect.Value{}, out, errDecode
} }
m := list.NewElement() m := list.NewElement()
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
Buf: b, Buf: b,
Message: m.Message(), Message: m.Message(),
}) })
if err != nil { if err != nil {
return pref.Value{}, out, err return protoreflect.Value{}, out, err
} }
list.Append(m) list.Append(m)
out.n = n out.n = n
out.initialized = o.Flags&piface.UnmarshalInitialized != 0 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
return listv, out, nil return listv, out, nil
} }
@ -705,7 +707,7 @@ var coderGroupSliceValue = valueCoderFuncs{
merge: mergeMessageListValue, merge: mergeMessageListValue,
} }
func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
num := fd.Number() num := fd.Number()
if mi := getMessageInfo(ft); mi != nil { if mi := getMessageInfo(ft); mi != nil {
funcs := pointerCoderFuncs{ funcs := pointerCoderFuncs{
@ -767,10 +769,10 @@ func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire
} }
b, n := protowire.ConsumeGroup(num, b) b, n := protowire.ConsumeGroup(num, b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
mp := reflect.New(goType.Elem()) mp := reflect.New(goType.Elem())
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
Buf: b, Buf: b,
Message: asMessage(mp).ProtoReflect(), Message: asMessage(mp).ProtoReflect(),
}) })
@ -779,7 +781,7 @@ func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire
} }
p.AppendPointerSlice(pointerOfValue(mp)) p.AppendPointerSlice(pointerOfValue(mp))
out.n = n out.n = n
out.initialized = o.Flags&piface.UnmarshalInitialized != 0 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
return out, nil return out, nil
} }
@ -820,8 +822,8 @@ func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFie
return out, nil return out, nil
} }
func asMessage(v reflect.Value) pref.ProtoMessage { func asMessage(v reflect.Value) protoreflect.ProtoMessage {
if m, ok := v.Interface().(pref.ProtoMessage); ok { if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
return m return m
} }
return legacyWrapMessage(v).Interface() return legacyWrapMessage(v).Interface()

File diff suppressed because it is too large Load Diff

View File

@ -5,13 +5,12 @@
package impl package impl
import ( import (
"errors"
"reflect" "reflect"
"sort" "sort"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type mapInfo struct { type mapInfo struct {
@ -20,12 +19,12 @@ type mapInfo struct {
valWiretag uint64 valWiretag uint64
keyFuncs valueCoderFuncs keyFuncs valueCoderFuncs
valFuncs valueCoderFuncs valFuncs valueCoderFuncs
keyZero pref.Value keyZero protoreflect.Value
keyKind pref.Kind keyKind protoreflect.Kind
conv *mapConverter conv *mapConverter
} }
func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) { func encoderFuncsForMap(fd protoreflect.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) {
// TODO: Consider generating specialized map coders. // TODO: Consider generating specialized map coders.
keyField := fd.MapKey() keyField := fd.MapKey()
valField := fd.MapValue() valField := fd.MapValue()
@ -45,7 +44,7 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage
keyKind: keyField.Kind(), keyKind: keyField.Kind(),
conv: conv, conv: conv,
} }
if valField.Kind() == pref.MessageKind { if valField.Kind() == protoreflect.MessageKind {
valueMessage = getMessageInfo(ft.Elem()) valueMessage = getMessageInfo(ft.Elem())
} }
@ -69,9 +68,9 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage
}, },
} }
switch valField.Kind() { switch valField.Kind() {
case pref.MessageKind: case protoreflect.MessageKind:
funcs.merge = mergeMapOfMessage funcs.merge = mergeMapOfMessage
case pref.BytesKind: case protoreflect.BytesKind:
funcs.merge = mergeMapOfBytes funcs.merge = mergeMapOfBytes
default: default:
funcs.merge = mergeMap funcs.merge = mergeMap
@ -118,7 +117,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo
} }
b, n := protowire.ConsumeBytes(b) b, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
var ( var (
key = mapi.keyZero key = mapi.keyZero
@ -127,16 +126,16 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo
for len(b) > 0 { for len(b) > 0 {
num, wtyp, n := protowire.ConsumeTag(b) num, wtyp, n := protowire.ConsumeTag(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
if num > protowire.MaxValidNumber { if num > protowire.MaxValidNumber {
return out, errors.New("invalid field number") return out, errDecode
} }
b = b[n:] b = b[n:]
err := errUnknown err := errUnknown
switch num { switch num {
case genid.MapEntry_Key_field_number: case genid.MapEntry_Key_field_number:
var v pref.Value var v protoreflect.Value
var o unmarshalOutput var o unmarshalOutput
v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts) v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
if err != nil { if err != nil {
@ -145,7 +144,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo
key = v key = v
n = o.n n = o.n
case genid.MapEntry_Value_field_number: case genid.MapEntry_Value_field_number:
var v pref.Value var v protoreflect.Value
var o unmarshalOutput var o unmarshalOutput
v, o, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts) v, o, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts)
if err != nil { if err != nil {
@ -157,7 +156,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo
if err == errUnknown { if err == errUnknown {
n = protowire.ConsumeFieldValue(num, wtyp, b) n = protowire.ConsumeFieldValue(num, wtyp, b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
} else if err != nil { } else if err != nil {
return out, err return out, err
@ -175,7 +174,7 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi
} }
b, n := protowire.ConsumeBytes(b) b, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
var ( var (
key = mapi.keyZero key = mapi.keyZero
@ -184,16 +183,16 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi
for len(b) > 0 { for len(b) > 0 {
num, wtyp, n := protowire.ConsumeTag(b) num, wtyp, n := protowire.ConsumeTag(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
if num > protowire.MaxValidNumber { if num > protowire.MaxValidNumber {
return out, errors.New("invalid field number") return out, errDecode
} }
b = b[n:] b = b[n:]
err := errUnknown err := errUnknown
switch num { switch num {
case 1: case 1:
var v pref.Value var v protoreflect.Value
var o unmarshalOutput var o unmarshalOutput
v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts) v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
if err != nil { if err != nil {
@ -208,7 +207,7 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi
var v []byte var v []byte
v, n = protowire.ConsumeBytes(b) v, n = protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
var o unmarshalOutput var o unmarshalOutput
o, err = f.mi.unmarshalPointer(v, pointerOfValue(val), 0, opts) o, err = f.mi.unmarshalPointer(v, pointerOfValue(val), 0, opts)
@ -221,7 +220,7 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi
if err == errUnknown { if err == errUnknown {
n = protowire.ConsumeFieldValue(num, wtyp, b) n = protowire.ConsumeFieldValue(num, wtyp, b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
} else if err != nil { } else if err != nil {
return out, err return out, err

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !go1.12
// +build !go1.12 // +build !go1.12
package impl package impl

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.12
// +build go1.12 // +build go1.12
package impl package impl

View File

@ -11,22 +11,23 @@ import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/fieldsort" "google.golang.org/protobuf/internal/order"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
// coderMessageInfo contains per-message information used by the fast-path functions. // coderMessageInfo contains per-message information used by the fast-path functions.
// This is a different type from MessageInfo to keep MessageInfo as general-purpose as // This is a different type from MessageInfo to keep MessageInfo as general-purpose as
// possible. // possible.
type coderMessageInfo struct { type coderMessageInfo struct {
methods piface.Methods methods protoiface.Methods
orderedCoderFields []*coderFieldInfo orderedCoderFields []*coderFieldInfo
denseCoderFields []*coderFieldInfo denseCoderFields []*coderFieldInfo
coderFields map[protowire.Number]*coderFieldInfo coderFields map[protowire.Number]*coderFieldInfo
sizecacheOffset offset sizecacheOffset offset
unknownOffset offset unknownOffset offset
unknownPtrKind bool
extensionOffset offset extensionOffset offset
needsInitCheck bool needsInitCheck bool
isMessageSet bool isMessageSet bool
@ -38,7 +39,7 @@ type coderFieldInfo struct {
mi *MessageInfo // field's message mi *MessageInfo // field's message
ft reflect.Type ft reflect.Type
validation validationInfo // information used by message validation validation validationInfo // information used by message validation
num pref.FieldNumber // field number num protoreflect.FieldNumber // field number
offset offset // struct field offset offset offset // struct field offset
wiretag uint64 // field tag (number + wire type) wiretag uint64 // field tag (number + wire type)
tagsize int // size of the varint-encoded tag tagsize int // size of the varint-encoded tag
@ -47,9 +48,20 @@ type coderFieldInfo struct {
} }
func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
mi.sizecacheOffset = invalidOffset
mi.unknownOffset = invalidOffset
mi.extensionOffset = invalidOffset
if si.sizecacheOffset.IsValid() && si.sizecacheType == sizecacheType {
mi.sizecacheOffset = si.sizecacheOffset mi.sizecacheOffset = si.sizecacheOffset
}
if si.unknownOffset.IsValid() && (si.unknownType == unknownFieldsAType || si.unknownType == unknownFieldsBType) {
mi.unknownOffset = si.unknownOffset mi.unknownOffset = si.unknownOffset
mi.unknownPtrKind = si.unknownType.Kind() == reflect.Ptr
}
if si.extensionOffset.IsValid() && si.extensionType == extensionFieldsType {
mi.extensionOffset = si.extensionOffset mi.extensionOffset = si.extensionOffset
}
mi.coderFields = make(map[protowire.Number]*coderFieldInfo) mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
fields := mi.Desc.Fields() fields := mi.Desc.Fields()
@ -73,6 +85,27 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
var funcs pointerCoderFuncs var funcs pointerCoderFuncs
var childMessage *MessageInfo var childMessage *MessageInfo
switch { switch {
case ft == nil:
// This never occurs for generated message types.
// It implies that a hand-crafted type has missing Go fields
// for specific protobuf message fields.
funcs = pointerCoderFuncs{
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
return 0
},
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
return nil, nil
},
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
panic("missing Go struct field for " + string(fd.FullName()))
},
isInit: func(p pointer, f *coderFieldInfo) error {
panic("missing Go struct field for " + string(fd.FullName()))
},
merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
panic("missing Go struct field for " + string(fd.FullName()))
},
}
case isOneof: case isOneof:
fieldOffset = offsetOf(fs, mi.Exporter) fieldOffset = offsetOf(fs, mi.Exporter)
case fd.IsWeak(): case fd.IsWeak():
@ -92,8 +125,8 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
funcs: funcs, funcs: funcs,
mi: childMessage, mi: childMessage,
validation: newFieldValidationInfo(mi, si, fd, ft), validation: newFieldValidationInfo(mi, si, fd, ft),
isPointer: fd.Cardinality() == pref.Repeated || fd.HasPresence(), isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(),
isRequired: fd.Cardinality() == pref.Required, isRequired: fd.Cardinality() == protoreflect.Required,
} }
mi.orderedCoderFields = append(mi.orderedCoderFields, cf) mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
mi.coderFields[cf.num] = cf mi.coderFields[cf.num] = cf
@ -116,7 +149,7 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
}) })
var maxDense pref.FieldNumber var maxDense protoreflect.FieldNumber
for _, cf := range mi.orderedCoderFields { for _, cf := range mi.orderedCoderFields {
if cf.num >= 16 && cf.num >= 2*maxDense { if cf.num >= 16 && cf.num >= 2*maxDense {
break break
@ -136,18 +169,18 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
sort.Slice(mi.orderedCoderFields, func(i, j int) bool { sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
fi := fields.ByNumber(mi.orderedCoderFields[i].num) fi := fields.ByNumber(mi.orderedCoderFields[i].num)
fj := fields.ByNumber(mi.orderedCoderFields[j].num) fj := fields.ByNumber(mi.orderedCoderFields[j].num)
return fieldsort.Less(fi, fj) return order.LegacyFieldOrder(fi, fj)
}) })
} }
mi.needsInitCheck = needsInitCheck(mi.Desc) mi.needsInitCheck = needsInitCheck(mi.Desc)
if mi.methods.Marshal == nil && mi.methods.Size == nil { if mi.methods.Marshal == nil && mi.methods.Size == nil {
mi.methods.Flags |= piface.SupportMarshalDeterministic mi.methods.Flags |= protoiface.SupportMarshalDeterministic
mi.methods.Marshal = mi.marshal mi.methods.Marshal = mi.marshal
mi.methods.Size = mi.size mi.methods.Size = mi.size
} }
if mi.methods.Unmarshal == nil { if mi.methods.Unmarshal == nil {
mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown mi.methods.Flags |= protoiface.SupportUnmarshalDiscardUnknown
mi.methods.Unmarshal = mi.unmarshal mi.methods.Unmarshal = mi.unmarshal
} }
if mi.methods.CheckInitialized == nil { if mi.methods.CheckInitialized == nil {
@ -157,3 +190,28 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
mi.methods.Merge = mi.merge mi.methods.Merge = mi.merge
} }
} }
// getUnknownBytes returns a *[]byte for the unknown fields.
// It is the caller's responsibility to check whether the pointer is nil.
// This function is specially designed to be inlineable.
func (mi *MessageInfo) getUnknownBytes(p pointer) *[]byte {
if mi.unknownPtrKind {
return *p.Apply(mi.unknownOffset).BytesPtr()
} else {
return p.Apply(mi.unknownOffset).Bytes()
}
}
// mutableUnknownBytes returns a *[]byte for the unknown fields.
// The returned pointer is guaranteed to not be nil.
func (mi *MessageInfo) mutableUnknownBytes(p pointer) *[]byte {
if mi.unknownPtrKind {
bp := p.Apply(mi.unknownOffset).BytesPtr()
if *bp == nil {
*bp = new([]byte)
}
return *bp
} else {
return p.Apply(mi.unknownOffset).Bytes()
}
}

View File

@ -29,8 +29,9 @@ func sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int)
size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts) size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts)
} }
unknown := *p.Apply(mi.unknownOffset).Bytes() if u := mi.getUnknownBytes(p); u != nil {
size += messageset.SizeUnknown(unknown) size += messageset.SizeUnknown(*u)
}
return size return size
} }
@ -69,11 +70,13 @@ func marshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts marshalOptions
} }
} }
unknown := *p.Apply(mi.unknownOffset).Bytes() if u := mi.getUnknownBytes(p); u != nil {
b, err := messageset.AppendUnknown(b, unknown) var err error
b, err = messageset.AppendUnknown(b, *u)
if err != nil { if err != nil {
return b, err return b, err
} }
}
return b, nil return b, nil
} }
@ -100,13 +103,13 @@ func unmarshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts unmarshalOpt
*ep = make(map[int32]ExtensionField) *ep = make(map[int32]ExtensionField)
} }
ext := *ep ext := *ep
unknown := p.Apply(mi.unknownOffset).Bytes()
initialized := true initialized := true
err = messageset.Unmarshal(b, true, func(num protowire.Number, v []byte) error { err = messageset.Unmarshal(b, true, func(num protowire.Number, v []byte) error {
o, err := mi.unmarshalExtension(v, num, protowire.BytesType, ext, opts) o, err := mi.unmarshalExtension(v, num, protowire.BytesType, ext, opts)
if err == errUnknown { if err == errUnknown {
*unknown = protowire.AppendTag(*unknown, num, protowire.BytesType) u := mi.mutableUnknownBytes(p)
*unknown = append(*unknown, v...) *u = protowire.AppendTag(*u, num, protowire.BytesType)
*u = append(*u, v...)
return nil return nil
} }
if !o.initialized { if !o.initialized {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build purego || appengine
// +build purego appengine // +build purego appengine
package impl package impl
@ -30,7 +31,7 @@ func consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
p.v.Elem().SetInt(int64(v)) p.v.Elem().SetInt(int64(v))
out.n = n out.n = n
@ -130,12 +131,12 @@ func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInf
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
b, n := protowire.ConsumeBytes(b) b, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
for len(b) > 0 { for len(b) > 0 {
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
rv := reflect.New(s.Type().Elem()).Elem() rv := reflect.New(s.Type().Elem()).Elem()
rv.SetInt(int64(v)) rv.SetInt(int64(v))
@ -150,7 +151,7 @@ func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInf
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
rv := reflect.New(s.Type().Elem()).Elem() rv := reflect.New(s.Type().Elem()).Elem()
rv.SetInt(int64(v)) rv.SetInt(int64(v))

View File

@ -10,7 +10,7 @@ import (
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
// pointerCoderFuncs is a set of pointer encoding functions. // pointerCoderFuncs is a set of pointer encoding functions.
@ -25,83 +25,83 @@ type pointerCoderFuncs struct {
// valueCoderFuncs is a set of protoreflect.Value encoding functions. // valueCoderFuncs is a set of protoreflect.Value encoding functions.
type valueCoderFuncs struct { type valueCoderFuncs struct {
size func(v pref.Value, tagsize int, opts marshalOptions) int size func(v protoreflect.Value, tagsize int, opts marshalOptions) int
marshal func(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) marshal func(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error)
unmarshal func(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) unmarshal func(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error)
isInit func(v pref.Value) error isInit func(v protoreflect.Value) error
merge func(dst, src pref.Value, opts mergeOptions) pref.Value merge func(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value
} }
// fieldCoder returns pointer functions for a field, used for operating on // fieldCoder returns pointer functions for a field, used for operating on
// struct fields. // struct fields.
func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) { func fieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
switch { switch {
case fd.IsMap(): case fd.IsMap():
return encoderFuncsForMap(fd, ft) return encoderFuncsForMap(fd, ft)
case fd.Cardinality() == pref.Repeated && !fd.IsPacked(): case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked():
// Repeated fields (not packed). // Repeated fields (not packed).
if ft.Kind() != reflect.Slice { if ft.Kind() != reflect.Slice {
break break
} }
ft := ft.Elem() ft := ft.Elem()
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
if ft.Kind() == reflect.Bool { if ft.Kind() == reflect.Bool {
return nil, coderBoolSlice return nil, coderBoolSlice
} }
case pref.EnumKind: case protoreflect.EnumKind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderEnumSlice return nil, coderEnumSlice
} }
case pref.Int32Kind: case protoreflect.Int32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderInt32Slice return nil, coderInt32Slice
} }
case pref.Sint32Kind: case protoreflect.Sint32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSint32Slice return nil, coderSint32Slice
} }
case pref.Uint32Kind: case protoreflect.Uint32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderUint32Slice return nil, coderUint32Slice
} }
case pref.Int64Kind: case protoreflect.Int64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderInt64Slice return nil, coderInt64Slice
} }
case pref.Sint64Kind: case protoreflect.Sint64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSint64Slice return nil, coderSint64Slice
} }
case pref.Uint64Kind: case protoreflect.Uint64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderUint64Slice return nil, coderUint64Slice
} }
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSfixed32Slice return nil, coderSfixed32Slice
} }
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderFixed32Slice return nil, coderFixed32Slice
} }
case pref.FloatKind: case protoreflect.FloatKind:
if ft.Kind() == reflect.Float32 { if ft.Kind() == reflect.Float32 {
return nil, coderFloatSlice return nil, coderFloatSlice
} }
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSfixed64Slice return nil, coderSfixed64Slice
} }
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderFixed64Slice return nil, coderFixed64Slice
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if ft.Kind() == reflect.Float64 { if ft.Kind() == reflect.Float64 {
return nil, coderDoubleSlice return nil, coderDoubleSlice
} }
case pref.StringKind: case protoreflect.StringKind:
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
return nil, coderStringSliceValidateUTF8 return nil, coderStringSliceValidateUTF8
} }
@ -114,19 +114,19 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
return nil, coderBytesSlice return nil, coderBytesSlice
} }
case pref.BytesKind: case protoreflect.BytesKind:
if ft.Kind() == reflect.String { if ft.Kind() == reflect.String {
return nil, coderStringSlice return nil, coderStringSlice
} }
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
return nil, coderBytesSlice return nil, coderBytesSlice
} }
case pref.MessageKind: case protoreflect.MessageKind:
return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft) return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
case pref.GroupKind: case protoreflect.GroupKind:
return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft) return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
} }
case fd.Cardinality() == pref.Repeated && fd.IsPacked(): case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked():
// Packed repeated fields. // Packed repeated fields.
// //
// Only repeated fields of primitive numeric types // Only repeated fields of primitive numeric types
@ -136,128 +136,128 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
} }
ft := ft.Elem() ft := ft.Elem()
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
if ft.Kind() == reflect.Bool { if ft.Kind() == reflect.Bool {
return nil, coderBoolPackedSlice return nil, coderBoolPackedSlice
} }
case pref.EnumKind: case protoreflect.EnumKind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderEnumPackedSlice return nil, coderEnumPackedSlice
} }
case pref.Int32Kind: case protoreflect.Int32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderInt32PackedSlice return nil, coderInt32PackedSlice
} }
case pref.Sint32Kind: case protoreflect.Sint32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSint32PackedSlice return nil, coderSint32PackedSlice
} }
case pref.Uint32Kind: case protoreflect.Uint32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderUint32PackedSlice return nil, coderUint32PackedSlice
} }
case pref.Int64Kind: case protoreflect.Int64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderInt64PackedSlice return nil, coderInt64PackedSlice
} }
case pref.Sint64Kind: case protoreflect.Sint64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSint64PackedSlice return nil, coderSint64PackedSlice
} }
case pref.Uint64Kind: case protoreflect.Uint64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderUint64PackedSlice return nil, coderUint64PackedSlice
} }
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSfixed32PackedSlice return nil, coderSfixed32PackedSlice
} }
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderFixed32PackedSlice return nil, coderFixed32PackedSlice
} }
case pref.FloatKind: case protoreflect.FloatKind:
if ft.Kind() == reflect.Float32 { if ft.Kind() == reflect.Float32 {
return nil, coderFloatPackedSlice return nil, coderFloatPackedSlice
} }
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSfixed64PackedSlice return nil, coderSfixed64PackedSlice
} }
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderFixed64PackedSlice return nil, coderFixed64PackedSlice
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if ft.Kind() == reflect.Float64 { if ft.Kind() == reflect.Float64 {
return nil, coderDoublePackedSlice return nil, coderDoublePackedSlice
} }
} }
case fd.Kind() == pref.MessageKind: case fd.Kind() == protoreflect.MessageKind:
return getMessageInfo(ft), makeMessageFieldCoder(fd, ft) return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
case fd.Kind() == pref.GroupKind: case fd.Kind() == protoreflect.GroupKind:
return getMessageInfo(ft), makeGroupFieldCoder(fd, ft) return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil: case fd.Syntax() == protoreflect.Proto3 && fd.ContainingOneof() == nil:
// Populated oneof fields always encode even if set to the zero value, // Populated oneof fields always encode even if set to the zero value,
// which normally are not encoded in proto3. // which normally are not encoded in proto3.
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
if ft.Kind() == reflect.Bool { if ft.Kind() == reflect.Bool {
return nil, coderBoolNoZero return nil, coderBoolNoZero
} }
case pref.EnumKind: case protoreflect.EnumKind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderEnumNoZero return nil, coderEnumNoZero
} }
case pref.Int32Kind: case protoreflect.Int32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderInt32NoZero return nil, coderInt32NoZero
} }
case pref.Sint32Kind: case protoreflect.Sint32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSint32NoZero return nil, coderSint32NoZero
} }
case pref.Uint32Kind: case protoreflect.Uint32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderUint32NoZero return nil, coderUint32NoZero
} }
case pref.Int64Kind: case protoreflect.Int64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderInt64NoZero return nil, coderInt64NoZero
} }
case pref.Sint64Kind: case protoreflect.Sint64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSint64NoZero return nil, coderSint64NoZero
} }
case pref.Uint64Kind: case protoreflect.Uint64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderUint64NoZero return nil, coderUint64NoZero
} }
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSfixed32NoZero return nil, coderSfixed32NoZero
} }
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderFixed32NoZero return nil, coderFixed32NoZero
} }
case pref.FloatKind: case protoreflect.FloatKind:
if ft.Kind() == reflect.Float32 { if ft.Kind() == reflect.Float32 {
return nil, coderFloatNoZero return nil, coderFloatNoZero
} }
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSfixed64NoZero return nil, coderSfixed64NoZero
} }
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderFixed64NoZero return nil, coderFixed64NoZero
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if ft.Kind() == reflect.Float64 { if ft.Kind() == reflect.Float64 {
return nil, coderDoubleNoZero return nil, coderDoubleNoZero
} }
case pref.StringKind: case protoreflect.StringKind:
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
return nil, coderStringNoZeroValidateUTF8 return nil, coderStringNoZeroValidateUTF8
} }
@ -270,7 +270,7 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
return nil, coderBytesNoZero return nil, coderBytesNoZero
} }
case pref.BytesKind: case protoreflect.BytesKind:
if ft.Kind() == reflect.String { if ft.Kind() == reflect.String {
return nil, coderStringNoZero return nil, coderStringNoZero
} }
@ -281,133 +281,133 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
case ft.Kind() == reflect.Ptr: case ft.Kind() == reflect.Ptr:
ft := ft.Elem() ft := ft.Elem()
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
if ft.Kind() == reflect.Bool { if ft.Kind() == reflect.Bool {
return nil, coderBoolPtr return nil, coderBoolPtr
} }
case pref.EnumKind: case protoreflect.EnumKind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderEnumPtr return nil, coderEnumPtr
} }
case pref.Int32Kind: case protoreflect.Int32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderInt32Ptr return nil, coderInt32Ptr
} }
case pref.Sint32Kind: case protoreflect.Sint32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSint32Ptr return nil, coderSint32Ptr
} }
case pref.Uint32Kind: case protoreflect.Uint32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderUint32Ptr return nil, coderUint32Ptr
} }
case pref.Int64Kind: case protoreflect.Int64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderInt64Ptr return nil, coderInt64Ptr
} }
case pref.Sint64Kind: case protoreflect.Sint64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSint64Ptr return nil, coderSint64Ptr
} }
case pref.Uint64Kind: case protoreflect.Uint64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderUint64Ptr return nil, coderUint64Ptr
} }
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSfixed32Ptr return nil, coderSfixed32Ptr
} }
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderFixed32Ptr return nil, coderFixed32Ptr
} }
case pref.FloatKind: case protoreflect.FloatKind:
if ft.Kind() == reflect.Float32 { if ft.Kind() == reflect.Float32 {
return nil, coderFloatPtr return nil, coderFloatPtr
} }
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSfixed64Ptr return nil, coderSfixed64Ptr
} }
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderFixed64Ptr return nil, coderFixed64Ptr
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if ft.Kind() == reflect.Float64 { if ft.Kind() == reflect.Float64 {
return nil, coderDoublePtr return nil, coderDoublePtr
} }
case pref.StringKind: case protoreflect.StringKind:
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
return nil, coderStringPtrValidateUTF8 return nil, coderStringPtrValidateUTF8
} }
if ft.Kind() == reflect.String { if ft.Kind() == reflect.String {
return nil, coderStringPtr return nil, coderStringPtr
} }
case pref.BytesKind: case protoreflect.BytesKind:
if ft.Kind() == reflect.String { if ft.Kind() == reflect.String {
return nil, coderStringPtr return nil, coderStringPtr
} }
} }
default: default:
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
if ft.Kind() == reflect.Bool { if ft.Kind() == reflect.Bool {
return nil, coderBool return nil, coderBool
} }
case pref.EnumKind: case protoreflect.EnumKind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderEnum return nil, coderEnum
} }
case pref.Int32Kind: case protoreflect.Int32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderInt32 return nil, coderInt32
} }
case pref.Sint32Kind: case protoreflect.Sint32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSint32 return nil, coderSint32
} }
case pref.Uint32Kind: case protoreflect.Uint32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderUint32 return nil, coderUint32
} }
case pref.Int64Kind: case protoreflect.Int64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderInt64 return nil, coderInt64
} }
case pref.Sint64Kind: case protoreflect.Sint64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSint64 return nil, coderSint64
} }
case pref.Uint64Kind: case protoreflect.Uint64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderUint64 return nil, coderUint64
} }
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
if ft.Kind() == reflect.Int32 { if ft.Kind() == reflect.Int32 {
return nil, coderSfixed32 return nil, coderSfixed32
} }
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
if ft.Kind() == reflect.Uint32 { if ft.Kind() == reflect.Uint32 {
return nil, coderFixed32 return nil, coderFixed32
} }
case pref.FloatKind: case protoreflect.FloatKind:
if ft.Kind() == reflect.Float32 { if ft.Kind() == reflect.Float32 {
return nil, coderFloat return nil, coderFloat
} }
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
if ft.Kind() == reflect.Int64 { if ft.Kind() == reflect.Int64 {
return nil, coderSfixed64 return nil, coderSfixed64
} }
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
if ft.Kind() == reflect.Uint64 { if ft.Kind() == reflect.Uint64 {
return nil, coderFixed64 return nil, coderFixed64
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if ft.Kind() == reflect.Float64 { if ft.Kind() == reflect.Float64 {
return nil, coderDouble return nil, coderDouble
} }
case pref.StringKind: case protoreflect.StringKind:
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
return nil, coderStringValidateUTF8 return nil, coderStringValidateUTF8
} }
@ -420,7 +420,7 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
return nil, coderBytes return nil, coderBytes
} }
case pref.BytesKind: case protoreflect.BytesKind:
if ft.Kind() == reflect.String { if ft.Kind() == reflect.String {
return nil, coderString return nil, coderString
} }
@ -434,122 +434,122 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
// encoderFuncsForValue returns value functions for a field, used for // encoderFuncsForValue returns value functions for a field, used for
// extension values and map encoding. // extension values and map encoding.
func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs { func encoderFuncsForValue(fd protoreflect.FieldDescriptor) valueCoderFuncs {
switch { switch {
case fd.Cardinality() == pref.Repeated && !fd.IsPacked(): case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked():
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
return coderBoolSliceValue return coderBoolSliceValue
case pref.EnumKind: case protoreflect.EnumKind:
return coderEnumSliceValue return coderEnumSliceValue
case pref.Int32Kind: case protoreflect.Int32Kind:
return coderInt32SliceValue return coderInt32SliceValue
case pref.Sint32Kind: case protoreflect.Sint32Kind:
return coderSint32SliceValue return coderSint32SliceValue
case pref.Uint32Kind: case protoreflect.Uint32Kind:
return coderUint32SliceValue return coderUint32SliceValue
case pref.Int64Kind: case protoreflect.Int64Kind:
return coderInt64SliceValue return coderInt64SliceValue
case pref.Sint64Kind: case protoreflect.Sint64Kind:
return coderSint64SliceValue return coderSint64SliceValue
case pref.Uint64Kind: case protoreflect.Uint64Kind:
return coderUint64SliceValue return coderUint64SliceValue
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
return coderSfixed32SliceValue return coderSfixed32SliceValue
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
return coderFixed32SliceValue return coderFixed32SliceValue
case pref.FloatKind: case protoreflect.FloatKind:
return coderFloatSliceValue return coderFloatSliceValue
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
return coderSfixed64SliceValue return coderSfixed64SliceValue
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
return coderFixed64SliceValue return coderFixed64SliceValue
case pref.DoubleKind: case protoreflect.DoubleKind:
return coderDoubleSliceValue return coderDoubleSliceValue
case pref.StringKind: case protoreflect.StringKind:
// We don't have a UTF-8 validating coder for repeated string fields. // We don't have a UTF-8 validating coder for repeated string fields.
// Value coders are used for extensions and maps. // Value coders are used for extensions and maps.
// Extensions are never proto3, and maps never contain lists. // Extensions are never proto3, and maps never contain lists.
return coderStringSliceValue return coderStringSliceValue
case pref.BytesKind: case protoreflect.BytesKind:
return coderBytesSliceValue return coderBytesSliceValue
case pref.MessageKind: case protoreflect.MessageKind:
return coderMessageSliceValue return coderMessageSliceValue
case pref.GroupKind: case protoreflect.GroupKind:
return coderGroupSliceValue return coderGroupSliceValue
} }
case fd.Cardinality() == pref.Repeated && fd.IsPacked(): case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked():
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
return coderBoolPackedSliceValue return coderBoolPackedSliceValue
case pref.EnumKind: case protoreflect.EnumKind:
return coderEnumPackedSliceValue return coderEnumPackedSliceValue
case pref.Int32Kind: case protoreflect.Int32Kind:
return coderInt32PackedSliceValue return coderInt32PackedSliceValue
case pref.Sint32Kind: case protoreflect.Sint32Kind:
return coderSint32PackedSliceValue return coderSint32PackedSliceValue
case pref.Uint32Kind: case protoreflect.Uint32Kind:
return coderUint32PackedSliceValue return coderUint32PackedSliceValue
case pref.Int64Kind: case protoreflect.Int64Kind:
return coderInt64PackedSliceValue return coderInt64PackedSliceValue
case pref.Sint64Kind: case protoreflect.Sint64Kind:
return coderSint64PackedSliceValue return coderSint64PackedSliceValue
case pref.Uint64Kind: case protoreflect.Uint64Kind:
return coderUint64PackedSliceValue return coderUint64PackedSliceValue
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
return coderSfixed32PackedSliceValue return coderSfixed32PackedSliceValue
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
return coderFixed32PackedSliceValue return coderFixed32PackedSliceValue
case pref.FloatKind: case protoreflect.FloatKind:
return coderFloatPackedSliceValue return coderFloatPackedSliceValue
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
return coderSfixed64PackedSliceValue return coderSfixed64PackedSliceValue
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
return coderFixed64PackedSliceValue return coderFixed64PackedSliceValue
case pref.DoubleKind: case protoreflect.DoubleKind:
return coderDoublePackedSliceValue return coderDoublePackedSliceValue
} }
default: default:
switch fd.Kind() { switch fd.Kind() {
default: default:
case pref.BoolKind: case protoreflect.BoolKind:
return coderBoolValue return coderBoolValue
case pref.EnumKind: case protoreflect.EnumKind:
return coderEnumValue return coderEnumValue
case pref.Int32Kind: case protoreflect.Int32Kind:
return coderInt32Value return coderInt32Value
case pref.Sint32Kind: case protoreflect.Sint32Kind:
return coderSint32Value return coderSint32Value
case pref.Uint32Kind: case protoreflect.Uint32Kind:
return coderUint32Value return coderUint32Value
case pref.Int64Kind: case protoreflect.Int64Kind:
return coderInt64Value return coderInt64Value
case pref.Sint64Kind: case protoreflect.Sint64Kind:
return coderSint64Value return coderSint64Value
case pref.Uint64Kind: case protoreflect.Uint64Kind:
return coderUint64Value return coderUint64Value
case pref.Sfixed32Kind: case protoreflect.Sfixed32Kind:
return coderSfixed32Value return coderSfixed32Value
case pref.Fixed32Kind: case protoreflect.Fixed32Kind:
return coderFixed32Value return coderFixed32Value
case pref.FloatKind: case protoreflect.FloatKind:
return coderFloatValue return coderFloatValue
case pref.Sfixed64Kind: case protoreflect.Sfixed64Kind:
return coderSfixed64Value return coderSfixed64Value
case pref.Fixed64Kind: case protoreflect.Fixed64Kind:
return coderFixed64Value return coderFixed64Value
case pref.DoubleKind: case protoreflect.DoubleKind:
return coderDoubleValue return coderDoubleValue
case pref.StringKind: case protoreflect.StringKind:
if strs.EnforceUTF8(fd) { if strs.EnforceUTF8(fd) {
return coderStringValueValidateUTF8 return coderStringValueValidateUTF8
} }
return coderStringValue return coderStringValue
case pref.BytesKind: case protoreflect.BytesKind:
return coderBytesValue return coderBytesValue
case pref.MessageKind: case protoreflect.MessageKind:
return coderMessageValue return coderMessageValue
case pref.GroupKind: case protoreflect.GroupKind:
return coderGroupValue return coderGroupValue
} }
} }

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !purego && !appengine
// +build !purego,!appengine // +build !purego,!appengine
package impl package impl

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
// unwrapper unwraps the value to the underlying value. // unwrapper unwraps the value to the underlying value.
@ -20,13 +20,13 @@ type unwrapper interface {
// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types. // A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types.
type Converter interface { type Converter interface {
// PBValueOf converts a reflect.Value to a protoreflect.Value. // PBValueOf converts a reflect.Value to a protoreflect.Value.
PBValueOf(reflect.Value) pref.Value PBValueOf(reflect.Value) protoreflect.Value
// GoValueOf converts a protoreflect.Value to a reflect.Value. // GoValueOf converts a protoreflect.Value to a reflect.Value.
GoValueOf(pref.Value) reflect.Value GoValueOf(protoreflect.Value) reflect.Value
// IsValidPB returns whether a protoreflect.Value is compatible with this type. // IsValidPB returns whether a protoreflect.Value is compatible with this type.
IsValidPB(pref.Value) bool IsValidPB(protoreflect.Value) bool
// IsValidGo returns whether a reflect.Value is compatible with this type. // IsValidGo returns whether a reflect.Value is compatible with this type.
IsValidGo(reflect.Value) bool IsValidGo(reflect.Value) bool
@ -34,12 +34,12 @@ type Converter interface {
// New returns a new field value. // New returns a new field value.
// For scalars, it returns the default value of the field. // For scalars, it returns the default value of the field.
// For composite types, it returns a new mutable value. // For composite types, it returns a new mutable value.
New() pref.Value New() protoreflect.Value
// Zero returns a new field value. // Zero returns a new field value.
// For scalars, it returns the default value of the field. // For scalars, it returns the default value of the field.
// For composite types, it returns an immutable, empty value. // For composite types, it returns an immutable, empty value.
Zero() pref.Value Zero() protoreflect.Value
} }
// NewConverter matches a Go type with a protobuf field and returns a Converter // NewConverter matches a Go type with a protobuf field and returns a Converter
@ -50,7 +50,7 @@ type Converter interface {
// This matcher deliberately supports a wider range of Go types than what // This matcher deliberately supports a wider range of Go types than what
// protoc-gen-go historically generated to be able to automatically wrap some // protoc-gen-go historically generated to be able to automatically wrap some
// v1 messages generated by other forks of protoc-gen-go. // v1 messages generated by other forks of protoc-gen-go.
func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { func NewConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter {
switch { switch {
case fd.IsList(): case fd.IsList():
return newListConverter(t, fd) return newListConverter(t, fd)
@ -76,68 +76,68 @@ var (
) )
var ( var (
boolZero = pref.ValueOfBool(false) boolZero = protoreflect.ValueOfBool(false)
int32Zero = pref.ValueOfInt32(0) int32Zero = protoreflect.ValueOfInt32(0)
int64Zero = pref.ValueOfInt64(0) int64Zero = protoreflect.ValueOfInt64(0)
uint32Zero = pref.ValueOfUint32(0) uint32Zero = protoreflect.ValueOfUint32(0)
uint64Zero = pref.ValueOfUint64(0) uint64Zero = protoreflect.ValueOfUint64(0)
float32Zero = pref.ValueOfFloat32(0) float32Zero = protoreflect.ValueOfFloat32(0)
float64Zero = pref.ValueOfFloat64(0) float64Zero = protoreflect.ValueOfFloat64(0)
stringZero = pref.ValueOfString("") stringZero = protoreflect.ValueOfString("")
bytesZero = pref.ValueOfBytes(nil) bytesZero = protoreflect.ValueOfBytes(nil)
) )
func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { func newSingularConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter {
defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value { defVal := func(fd protoreflect.FieldDescriptor, zero protoreflect.Value) protoreflect.Value {
if fd.Cardinality() == pref.Repeated { if fd.Cardinality() == protoreflect.Repeated {
// Default isn't defined for repeated fields. // Default isn't defined for repeated fields.
return zero return zero
} }
return fd.Default() return fd.Default()
} }
switch fd.Kind() { switch fd.Kind() {
case pref.BoolKind: case protoreflect.BoolKind:
if t.Kind() == reflect.Bool { if t.Kind() == reflect.Bool {
return &boolConverter{t, defVal(fd, boolZero)} return &boolConverter{t, defVal(fd, boolZero)}
} }
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
if t.Kind() == reflect.Int32 { if t.Kind() == reflect.Int32 {
return &int32Converter{t, defVal(fd, int32Zero)} return &int32Converter{t, defVal(fd, int32Zero)}
} }
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
if t.Kind() == reflect.Int64 { if t.Kind() == reflect.Int64 {
return &int64Converter{t, defVal(fd, int64Zero)} return &int64Converter{t, defVal(fd, int64Zero)}
} }
case pref.Uint32Kind, pref.Fixed32Kind: case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
if t.Kind() == reflect.Uint32 { if t.Kind() == reflect.Uint32 {
return &uint32Converter{t, defVal(fd, uint32Zero)} return &uint32Converter{t, defVal(fd, uint32Zero)}
} }
case pref.Uint64Kind, pref.Fixed64Kind: case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
if t.Kind() == reflect.Uint64 { if t.Kind() == reflect.Uint64 {
return &uint64Converter{t, defVal(fd, uint64Zero)} return &uint64Converter{t, defVal(fd, uint64Zero)}
} }
case pref.FloatKind: case protoreflect.FloatKind:
if t.Kind() == reflect.Float32 { if t.Kind() == reflect.Float32 {
return &float32Converter{t, defVal(fd, float32Zero)} return &float32Converter{t, defVal(fd, float32Zero)}
} }
case pref.DoubleKind: case protoreflect.DoubleKind:
if t.Kind() == reflect.Float64 { if t.Kind() == reflect.Float64 {
return &float64Converter{t, defVal(fd, float64Zero)} return &float64Converter{t, defVal(fd, float64Zero)}
} }
case pref.StringKind: case protoreflect.StringKind:
if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
return &stringConverter{t, defVal(fd, stringZero)} return &stringConverter{t, defVal(fd, stringZero)}
} }
case pref.BytesKind: case protoreflect.BytesKind:
if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
return &bytesConverter{t, defVal(fd, bytesZero)} return &bytesConverter{t, defVal(fd, bytesZero)}
} }
case pref.EnumKind: case protoreflect.EnumKind:
// Handle enums, which must be a named int32 type. // Handle enums, which must be a named int32 type.
if t.Kind() == reflect.Int32 { if t.Kind() == reflect.Int32 {
return newEnumConverter(t, fd) return newEnumConverter(t, fd)
} }
case pref.MessageKind, pref.GroupKind: case protoreflect.MessageKind, protoreflect.GroupKind:
return newMessageConverter(t) return newMessageConverter(t)
} }
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
@ -145,184 +145,184 @@ func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
type boolConverter struct { type boolConverter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *boolConverter) PBValueOf(v reflect.Value) pref.Value { func (c *boolConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfBool(v.Bool()) return protoreflect.ValueOfBool(v.Bool())
} }
func (c *boolConverter) GoValueOf(v pref.Value) reflect.Value { func (c *boolConverter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(v.Bool()).Convert(c.goType) return reflect.ValueOf(v.Bool()).Convert(c.goType)
} }
func (c *boolConverter) IsValidPB(v pref.Value) bool { func (c *boolConverter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(bool) _, ok := v.Interface().(bool)
return ok return ok
} }
func (c *boolConverter) IsValidGo(v reflect.Value) bool { func (c *boolConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *boolConverter) New() pref.Value { return c.def } func (c *boolConverter) New() protoreflect.Value { return c.def }
func (c *boolConverter) Zero() pref.Value { return c.def } func (c *boolConverter) Zero() protoreflect.Value { return c.def }
type int32Converter struct { type int32Converter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *int32Converter) PBValueOf(v reflect.Value) pref.Value { func (c *int32Converter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfInt32(int32(v.Int())) return protoreflect.ValueOfInt32(int32(v.Int()))
} }
func (c *int32Converter) GoValueOf(v pref.Value) reflect.Value { func (c *int32Converter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(int32(v.Int())).Convert(c.goType) return reflect.ValueOf(int32(v.Int())).Convert(c.goType)
} }
func (c *int32Converter) IsValidPB(v pref.Value) bool { func (c *int32Converter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(int32) _, ok := v.Interface().(int32)
return ok return ok
} }
func (c *int32Converter) IsValidGo(v reflect.Value) bool { func (c *int32Converter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *int32Converter) New() pref.Value { return c.def } func (c *int32Converter) New() protoreflect.Value { return c.def }
func (c *int32Converter) Zero() pref.Value { return c.def } func (c *int32Converter) Zero() protoreflect.Value { return c.def }
type int64Converter struct { type int64Converter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *int64Converter) PBValueOf(v reflect.Value) pref.Value { func (c *int64Converter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfInt64(int64(v.Int())) return protoreflect.ValueOfInt64(int64(v.Int()))
} }
func (c *int64Converter) GoValueOf(v pref.Value) reflect.Value { func (c *int64Converter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(int64(v.Int())).Convert(c.goType) return reflect.ValueOf(int64(v.Int())).Convert(c.goType)
} }
func (c *int64Converter) IsValidPB(v pref.Value) bool { func (c *int64Converter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(int64) _, ok := v.Interface().(int64)
return ok return ok
} }
func (c *int64Converter) IsValidGo(v reflect.Value) bool { func (c *int64Converter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *int64Converter) New() pref.Value { return c.def } func (c *int64Converter) New() protoreflect.Value { return c.def }
func (c *int64Converter) Zero() pref.Value { return c.def } func (c *int64Converter) Zero() protoreflect.Value { return c.def }
type uint32Converter struct { type uint32Converter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *uint32Converter) PBValueOf(v reflect.Value) pref.Value { func (c *uint32Converter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfUint32(uint32(v.Uint())) return protoreflect.ValueOfUint32(uint32(v.Uint()))
} }
func (c *uint32Converter) GoValueOf(v pref.Value) reflect.Value { func (c *uint32Converter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType) return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType)
} }
func (c *uint32Converter) IsValidPB(v pref.Value) bool { func (c *uint32Converter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(uint32) _, ok := v.Interface().(uint32)
return ok return ok
} }
func (c *uint32Converter) IsValidGo(v reflect.Value) bool { func (c *uint32Converter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *uint32Converter) New() pref.Value { return c.def } func (c *uint32Converter) New() protoreflect.Value { return c.def }
func (c *uint32Converter) Zero() pref.Value { return c.def } func (c *uint32Converter) Zero() protoreflect.Value { return c.def }
type uint64Converter struct { type uint64Converter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *uint64Converter) PBValueOf(v reflect.Value) pref.Value { func (c *uint64Converter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfUint64(uint64(v.Uint())) return protoreflect.ValueOfUint64(uint64(v.Uint()))
} }
func (c *uint64Converter) GoValueOf(v pref.Value) reflect.Value { func (c *uint64Converter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType) return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType)
} }
func (c *uint64Converter) IsValidPB(v pref.Value) bool { func (c *uint64Converter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(uint64) _, ok := v.Interface().(uint64)
return ok return ok
} }
func (c *uint64Converter) IsValidGo(v reflect.Value) bool { func (c *uint64Converter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *uint64Converter) New() pref.Value { return c.def } func (c *uint64Converter) New() protoreflect.Value { return c.def }
func (c *uint64Converter) Zero() pref.Value { return c.def } func (c *uint64Converter) Zero() protoreflect.Value { return c.def }
type float32Converter struct { type float32Converter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *float32Converter) PBValueOf(v reflect.Value) pref.Value { func (c *float32Converter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfFloat32(float32(v.Float())) return protoreflect.ValueOfFloat32(float32(v.Float()))
} }
func (c *float32Converter) GoValueOf(v pref.Value) reflect.Value { func (c *float32Converter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(float32(v.Float())).Convert(c.goType) return reflect.ValueOf(float32(v.Float())).Convert(c.goType)
} }
func (c *float32Converter) IsValidPB(v pref.Value) bool { func (c *float32Converter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(float32) _, ok := v.Interface().(float32)
return ok return ok
} }
func (c *float32Converter) IsValidGo(v reflect.Value) bool { func (c *float32Converter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *float32Converter) New() pref.Value { return c.def } func (c *float32Converter) New() protoreflect.Value { return c.def }
func (c *float32Converter) Zero() pref.Value { return c.def } func (c *float32Converter) Zero() protoreflect.Value { return c.def }
type float64Converter struct { type float64Converter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *float64Converter) PBValueOf(v reflect.Value) pref.Value { func (c *float64Converter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfFloat64(float64(v.Float())) return protoreflect.ValueOfFloat64(float64(v.Float()))
} }
func (c *float64Converter) GoValueOf(v pref.Value) reflect.Value { func (c *float64Converter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(float64(v.Float())).Convert(c.goType) return reflect.ValueOf(float64(v.Float())).Convert(c.goType)
} }
func (c *float64Converter) IsValidPB(v pref.Value) bool { func (c *float64Converter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(float64) _, ok := v.Interface().(float64)
return ok return ok
} }
func (c *float64Converter) IsValidGo(v reflect.Value) bool { func (c *float64Converter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *float64Converter) New() pref.Value { return c.def } func (c *float64Converter) New() protoreflect.Value { return c.def }
func (c *float64Converter) Zero() pref.Value { return c.def } func (c *float64Converter) Zero() protoreflect.Value { return c.def }
type stringConverter struct { type stringConverter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *stringConverter) PBValueOf(v reflect.Value) pref.Value { func (c *stringConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfString(v.Convert(stringType).String()) return protoreflect.ValueOfString(v.Convert(stringType).String())
} }
func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value { func (c *stringConverter) GoValueOf(v protoreflect.Value) reflect.Value {
// pref.Value.String never panics, so we go through an interface // pref.Value.String never panics, so we go through an interface
// conversion here to check the type. // conversion here to check the type.
s := v.Interface().(string) s := v.Interface().(string)
@ -331,71 +331,71 @@ func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value {
} }
return reflect.ValueOf(s).Convert(c.goType) return reflect.ValueOf(s).Convert(c.goType)
} }
func (c *stringConverter) IsValidPB(v pref.Value) bool { func (c *stringConverter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(string) _, ok := v.Interface().(string)
return ok return ok
} }
func (c *stringConverter) IsValidGo(v reflect.Value) bool { func (c *stringConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *stringConverter) New() pref.Value { return c.def } func (c *stringConverter) New() protoreflect.Value { return c.def }
func (c *stringConverter) Zero() pref.Value { return c.def } func (c *stringConverter) Zero() protoreflect.Value { return c.def }
type bytesConverter struct { type bytesConverter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func (c *bytesConverter) PBValueOf(v reflect.Value) pref.Value { func (c *bytesConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
if c.goType.Kind() == reflect.String && v.Len() == 0 { if c.goType.Kind() == reflect.String && v.Len() == 0 {
return pref.ValueOfBytes(nil) // ensure empty string is []byte(nil) return protoreflect.ValueOfBytes(nil) // ensure empty string is []byte(nil)
} }
return pref.ValueOfBytes(v.Convert(bytesType).Bytes()) return protoreflect.ValueOfBytes(v.Convert(bytesType).Bytes())
} }
func (c *bytesConverter) GoValueOf(v pref.Value) reflect.Value { func (c *bytesConverter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(v.Bytes()).Convert(c.goType) return reflect.ValueOf(v.Bytes()).Convert(c.goType)
} }
func (c *bytesConverter) IsValidPB(v pref.Value) bool { func (c *bytesConverter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().([]byte) _, ok := v.Interface().([]byte)
return ok return ok
} }
func (c *bytesConverter) IsValidGo(v reflect.Value) bool { func (c *bytesConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *bytesConverter) New() pref.Value { return c.def } func (c *bytesConverter) New() protoreflect.Value { return c.def }
func (c *bytesConverter) Zero() pref.Value { return c.def } func (c *bytesConverter) Zero() protoreflect.Value { return c.def }
type enumConverter struct { type enumConverter struct {
goType reflect.Type goType reflect.Type
def pref.Value def protoreflect.Value
} }
func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter { func newEnumConverter(goType reflect.Type, fd protoreflect.FieldDescriptor) Converter {
var def pref.Value var def protoreflect.Value
if fd.Cardinality() == pref.Repeated { if fd.Cardinality() == protoreflect.Repeated {
def = pref.ValueOfEnum(fd.Enum().Values().Get(0).Number()) def = protoreflect.ValueOfEnum(fd.Enum().Values().Get(0).Number())
} else { } else {
def = fd.Default() def = fd.Default()
} }
return &enumConverter{goType, def} return &enumConverter{goType, def}
} }
func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value { func (c *enumConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfEnum(pref.EnumNumber(v.Int())) return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v.Int()))
} }
func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value { func (c *enumConverter) GoValueOf(v protoreflect.Value) reflect.Value {
return reflect.ValueOf(v.Enum()).Convert(c.goType) return reflect.ValueOf(v.Enum()).Convert(c.goType)
} }
func (c *enumConverter) IsValidPB(v pref.Value) bool { func (c *enumConverter) IsValidPB(v protoreflect.Value) bool {
_, ok := v.Interface().(pref.EnumNumber) _, ok := v.Interface().(protoreflect.EnumNumber)
return ok return ok
} }
@ -403,11 +403,11 @@ func (c *enumConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *enumConverter) New() pref.Value { func (c *enumConverter) New() protoreflect.Value {
return c.def return c.def
} }
func (c *enumConverter) Zero() pref.Value { func (c *enumConverter) Zero() protoreflect.Value {
return c.def return c.def
} }
@ -419,17 +419,24 @@ func newMessageConverter(goType reflect.Type) Converter {
return &messageConverter{goType} return &messageConverter{goType}
} }
func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value { func (c *messageConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
if m, ok := v.Interface().(pref.ProtoMessage); ok { if c.isNonPointer() {
return pref.ValueOfMessage(m.ProtoReflect()) if v.CanAddr() {
v = v.Addr() // T => *T
} else {
v = reflect.Zero(reflect.PtrTo(v.Type()))
} }
return pref.ValueOfMessage(legacyWrapMessage(v)) }
if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
return protoreflect.ValueOfMessage(m.ProtoReflect())
}
return protoreflect.ValueOfMessage(legacyWrapMessage(v))
} }
func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value { func (c *messageConverter) GoValueOf(v protoreflect.Value) reflect.Value {
m := v.Message() m := v.Message()
var rv reflect.Value var rv reflect.Value
if u, ok := m.(unwrapper); ok { if u, ok := m.(unwrapper); ok {
@ -437,13 +444,23 @@ func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
} else { } else {
rv = reflect.ValueOf(m.Interface()) rv = reflect.ValueOf(m.Interface())
} }
if c.isNonPointer() {
if rv.Type() != reflect.PtrTo(c.goType) {
panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), reflect.PtrTo(c.goType)))
}
if !rv.IsNil() {
rv = rv.Elem() // *T => T
} else {
rv = reflect.Zero(rv.Type().Elem())
}
}
if rv.Type() != c.goType { if rv.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType))
} }
return rv return rv
} }
func (c *messageConverter) IsValidPB(v pref.Value) bool { func (c *messageConverter) IsValidPB(v protoreflect.Value) bool {
m := v.Message() m := v.Message()
var rv reflect.Value var rv reflect.Value
if u, ok := m.(unwrapper); ok { if u, ok := m.(unwrapper); ok {
@ -451,6 +468,9 @@ func (c *messageConverter) IsValidPB(v pref.Value) bool {
} else { } else {
rv = reflect.ValueOf(m.Interface()) rv = reflect.ValueOf(m.Interface())
} }
if c.isNonPointer() {
return rv.Type() == reflect.PtrTo(c.goType)
}
return rv.Type() == c.goType return rv.Type() == c.goType
} }
@ -458,10 +478,19 @@ func (c *messageConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *messageConverter) New() pref.Value { func (c *messageConverter) New() protoreflect.Value {
if c.isNonPointer() {
return c.PBValueOf(reflect.New(c.goType).Elem())
}
return c.PBValueOf(reflect.New(c.goType.Elem())) return c.PBValueOf(reflect.New(c.goType.Elem()))
} }
func (c *messageConverter) Zero() pref.Value { func (c *messageConverter) Zero() protoreflect.Value {
return c.PBValueOf(reflect.Zero(c.goType)) return c.PBValueOf(reflect.Zero(c.goType))
} }
// isNonPointer reports whether the type is a non-pointer type.
// This never occurs for generated message types.
func (c *messageConverter) isNonPointer() bool {
return c.goType.Kind() != reflect.Ptr
}

View File

@ -8,10 +8,10 @@ import (
"fmt" "fmt"
"reflect" "reflect"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { func newListConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter {
switch { switch {
case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice: case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice:
return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)} return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)}
@ -26,16 +26,16 @@ type listConverter struct {
c Converter c Converter
} }
func (c *listConverter) PBValueOf(v reflect.Value) pref.Value { func (c *listConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
pv := reflect.New(c.goType) pv := reflect.New(c.goType)
pv.Elem().Set(v) pv.Elem().Set(v)
return pref.ValueOfList(&listReflect{pv, c.c}) return protoreflect.ValueOfList(&listReflect{pv, c.c})
} }
func (c *listConverter) GoValueOf(v pref.Value) reflect.Value { func (c *listConverter) GoValueOf(v protoreflect.Value) reflect.Value {
rv := v.List().(*listReflect).v rv := v.List().(*listReflect).v
if rv.IsNil() { if rv.IsNil() {
return reflect.Zero(c.goType) return reflect.Zero(c.goType)
@ -43,7 +43,7 @@ func (c *listConverter) GoValueOf(v pref.Value) reflect.Value {
return rv.Elem() return rv.Elem()
} }
func (c *listConverter) IsValidPB(v pref.Value) bool { func (c *listConverter) IsValidPB(v protoreflect.Value) bool {
list, ok := v.Interface().(*listReflect) list, ok := v.Interface().(*listReflect)
if !ok { if !ok {
return false return false
@ -55,12 +55,12 @@ func (c *listConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *listConverter) New() pref.Value { func (c *listConverter) New() protoreflect.Value {
return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c}) return protoreflect.ValueOfList(&listReflect{reflect.New(c.goType), c.c})
} }
func (c *listConverter) Zero() pref.Value { func (c *listConverter) Zero() protoreflect.Value {
return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c}) return protoreflect.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c})
} }
type listPtrConverter struct { type listPtrConverter struct {
@ -68,18 +68,18 @@ type listPtrConverter struct {
c Converter c Converter
} }
func (c *listPtrConverter) PBValueOf(v reflect.Value) pref.Value { func (c *listPtrConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfList(&listReflect{v, c.c}) return protoreflect.ValueOfList(&listReflect{v, c.c})
} }
func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value { func (c *listPtrConverter) GoValueOf(v protoreflect.Value) reflect.Value {
return v.List().(*listReflect).v return v.List().(*listReflect).v
} }
func (c *listPtrConverter) IsValidPB(v pref.Value) bool { func (c *listPtrConverter) IsValidPB(v protoreflect.Value) bool {
list, ok := v.Interface().(*listReflect) list, ok := v.Interface().(*listReflect)
if !ok { if !ok {
return false return false
@ -91,11 +91,11 @@ func (c *listPtrConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *listPtrConverter) New() pref.Value { func (c *listPtrConverter) New() protoreflect.Value {
return c.PBValueOf(reflect.New(c.goType.Elem())) return c.PBValueOf(reflect.New(c.goType.Elem()))
} }
func (c *listPtrConverter) Zero() pref.Value { func (c *listPtrConverter) Zero() protoreflect.Value {
return c.PBValueOf(reflect.Zero(c.goType)) return c.PBValueOf(reflect.Zero(c.goType))
} }
@ -110,16 +110,16 @@ func (ls *listReflect) Len() int {
} }
return ls.v.Elem().Len() return ls.v.Elem().Len()
} }
func (ls *listReflect) Get(i int) pref.Value { func (ls *listReflect) Get(i int) protoreflect.Value {
return ls.conv.PBValueOf(ls.v.Elem().Index(i)) return ls.conv.PBValueOf(ls.v.Elem().Index(i))
} }
func (ls *listReflect) Set(i int, v pref.Value) { func (ls *listReflect) Set(i int, v protoreflect.Value) {
ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v)) ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
} }
func (ls *listReflect) Append(v pref.Value) { func (ls *listReflect) Append(v protoreflect.Value) {
ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v))) ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
} }
func (ls *listReflect) AppendMutable() pref.Value { func (ls *listReflect) AppendMutable() protoreflect.Value {
if _, ok := ls.conv.(*messageConverter); !ok { if _, ok := ls.conv.(*messageConverter); !ok {
panic("invalid AppendMutable on list with non-message type") panic("invalid AppendMutable on list with non-message type")
} }
@ -130,7 +130,7 @@ func (ls *listReflect) AppendMutable() pref.Value {
func (ls *listReflect) Truncate(i int) { func (ls *listReflect) Truncate(i int) {
ls.v.Elem().Set(ls.v.Elem().Slice(0, i)) ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
} }
func (ls *listReflect) NewElement() pref.Value { func (ls *listReflect) NewElement() protoreflect.Value {
return ls.conv.New() return ls.conv.New()
} }
func (ls *listReflect) IsValid() bool { func (ls *listReflect) IsValid() bool {

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type mapConverter struct { type mapConverter struct {
@ -16,7 +16,7 @@ type mapConverter struct {
keyConv, valConv Converter keyConv, valConv Converter
} }
func newMapConverter(t reflect.Type, fd pref.FieldDescriptor) *mapConverter { func newMapConverter(t reflect.Type, fd protoreflect.FieldDescriptor) *mapConverter {
if t.Kind() != reflect.Map { if t.Kind() != reflect.Map {
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
} }
@ -27,18 +27,18 @@ func newMapConverter(t reflect.Type, fd pref.FieldDescriptor) *mapConverter {
} }
} }
func (c *mapConverter) PBValueOf(v reflect.Value) pref.Value { func (c *mapConverter) PBValueOf(v reflect.Value) protoreflect.Value {
if v.Type() != c.goType { if v.Type() != c.goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
} }
return pref.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv}) return protoreflect.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv})
} }
func (c *mapConverter) GoValueOf(v pref.Value) reflect.Value { func (c *mapConverter) GoValueOf(v protoreflect.Value) reflect.Value {
return v.Map().(*mapReflect).v return v.Map().(*mapReflect).v
} }
func (c *mapConverter) IsValidPB(v pref.Value) bool { func (c *mapConverter) IsValidPB(v protoreflect.Value) bool {
mapv, ok := v.Interface().(*mapReflect) mapv, ok := v.Interface().(*mapReflect)
if !ok { if !ok {
return false return false
@ -50,11 +50,11 @@ func (c *mapConverter) IsValidGo(v reflect.Value) bool {
return v.IsValid() && v.Type() == c.goType return v.IsValid() && v.Type() == c.goType
} }
func (c *mapConverter) New() pref.Value { func (c *mapConverter) New() protoreflect.Value {
return c.PBValueOf(reflect.MakeMap(c.goType)) return c.PBValueOf(reflect.MakeMap(c.goType))
} }
func (c *mapConverter) Zero() pref.Value { func (c *mapConverter) Zero() protoreflect.Value {
return c.PBValueOf(reflect.Zero(c.goType)) return c.PBValueOf(reflect.Zero(c.goType))
} }
@ -67,29 +67,29 @@ type mapReflect struct {
func (ms *mapReflect) Len() int { func (ms *mapReflect) Len() int {
return ms.v.Len() return ms.v.Len()
} }
func (ms *mapReflect) Has(k pref.MapKey) bool { func (ms *mapReflect) Has(k protoreflect.MapKey) bool {
rk := ms.keyConv.GoValueOf(k.Value()) rk := ms.keyConv.GoValueOf(k.Value())
rv := ms.v.MapIndex(rk) rv := ms.v.MapIndex(rk)
return rv.IsValid() return rv.IsValid()
} }
func (ms *mapReflect) Get(k pref.MapKey) pref.Value { func (ms *mapReflect) Get(k protoreflect.MapKey) protoreflect.Value {
rk := ms.keyConv.GoValueOf(k.Value()) rk := ms.keyConv.GoValueOf(k.Value())
rv := ms.v.MapIndex(rk) rv := ms.v.MapIndex(rk)
if !rv.IsValid() { if !rv.IsValid() {
return pref.Value{} return protoreflect.Value{}
} }
return ms.valConv.PBValueOf(rv) return ms.valConv.PBValueOf(rv)
} }
func (ms *mapReflect) Set(k pref.MapKey, v pref.Value) { func (ms *mapReflect) Set(k protoreflect.MapKey, v protoreflect.Value) {
rk := ms.keyConv.GoValueOf(k.Value()) rk := ms.keyConv.GoValueOf(k.Value())
rv := ms.valConv.GoValueOf(v) rv := ms.valConv.GoValueOf(v)
ms.v.SetMapIndex(rk, rv) ms.v.SetMapIndex(rk, rv)
} }
func (ms *mapReflect) Clear(k pref.MapKey) { func (ms *mapReflect) Clear(k protoreflect.MapKey) {
rk := ms.keyConv.GoValueOf(k.Value()) rk := ms.keyConv.GoValueOf(k.Value())
ms.v.SetMapIndex(rk, reflect.Value{}) ms.v.SetMapIndex(rk, reflect.Value{})
} }
func (ms *mapReflect) Mutable(k pref.MapKey) pref.Value { func (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value {
if _, ok := ms.valConv.(*messageConverter); !ok { if _, ok := ms.valConv.(*messageConverter); !ok {
panic("invalid Mutable on map with non-message value type") panic("invalid Mutable on map with non-message value type")
} }
@ -100,7 +100,7 @@ func (ms *mapReflect) Mutable(k pref.MapKey) pref.Value {
} }
return v return v
} }
func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) { func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) {
iter := mapRange(ms.v) iter := mapRange(ms.v)
for iter.Next() { for iter.Next() {
k := ms.keyConv.PBValueOf(iter.Key()).MapKey() k := ms.keyConv.PBValueOf(iter.Key()).MapKey()
@ -110,7 +110,7 @@ func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
} }
} }
} }
func (ms *mapReflect) NewValue() pref.Value { func (ms *mapReflect) NewValue() protoreflect.Value {
return ms.valConv.New() return ms.valConv.New()
} }
func (ms *mapReflect) IsValid() bool { func (ms *mapReflect) IsValid() bool {

View File

@ -12,17 +12,20 @@ import (
"google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
piface "google.golang.org/protobuf/runtime/protoiface"
) )
var errDecode = errors.New("cannot parse invalid wire-format data")
var errRecursionDepth = errors.New("exceeded maximum recursion depth")
type unmarshalOptions struct { type unmarshalOptions struct {
flags protoiface.UnmarshalInputFlags flags protoiface.UnmarshalInputFlags
resolver interface { resolver interface {
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
} }
depth int
} }
func (o unmarshalOptions) Options() proto.UnmarshalOptions { func (o unmarshalOptions) Options() proto.UnmarshalOptions {
@ -34,14 +37,17 @@ func (o unmarshalOptions) Options() proto.UnmarshalOptions {
} }
} }
func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&piface.UnmarshalDiscardUnknown != 0 } func (o unmarshalOptions) DiscardUnknown() bool {
return o.flags&protoiface.UnmarshalDiscardUnknown != 0
}
func (o unmarshalOptions) IsDefault() bool { func (o unmarshalOptions) IsDefault() bool {
return o.flags == 0 && o.resolver == preg.GlobalTypes return o.flags == 0 && o.resolver == protoregistry.GlobalTypes
} }
var lazyUnmarshalOptions = unmarshalOptions{ var lazyUnmarshalOptions = unmarshalOptions{
resolver: preg.GlobalTypes, resolver: protoregistry.GlobalTypes,
depth: protowire.DefaultRecursionLimit,
} }
type unmarshalOutput struct { type unmarshalOutput struct {
@ -50,7 +56,7 @@ type unmarshalOutput struct {
} }
// unmarshal is protoreflect.Methods.Unmarshal. // unmarshal is protoreflect.Methods.Unmarshal.
func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) { func (mi *MessageInfo) unmarshal(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
var p pointer var p pointer
if ms, ok := in.Message.(*messageState); ok { if ms, ok := in.Message.(*messageState); ok {
p = ms.pointer() p = ms.pointer()
@ -60,12 +66,13 @@ func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutp
out, err := mi.unmarshalPointer(in.Buf, p, 0, unmarshalOptions{ out, err := mi.unmarshalPointer(in.Buf, p, 0, unmarshalOptions{
flags: in.Flags, flags: in.Flags,
resolver: in.Resolver, resolver: in.Resolver,
depth: in.Depth,
}) })
var flags piface.UnmarshalOutputFlags var flags protoiface.UnmarshalOutputFlags
if out.initialized { if out.initialized {
flags |= piface.UnmarshalInitialized flags |= protoiface.UnmarshalInitialized
} }
return piface.UnmarshalOutput{ return protoiface.UnmarshalOutput{
Flags: flags, Flags: flags,
}, err }, err
} }
@ -80,6 +87,10 @@ var errUnknown = errors.New("unknown")
func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) { func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) {
mi.init() mi.init()
opts.depth--
if opts.depth < 0 {
return out, errRecursionDepth
}
if flags.ProtoLegacy && mi.isMessageSet { if flags.ProtoLegacy && mi.isMessageSet {
return unmarshalMessageSet(mi, b, p, opts) return unmarshalMessageSet(mi, b, p, opts)
} }
@ -100,13 +111,13 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.
var n int var n int
tag, n = protowire.ConsumeVarint(b) tag, n = protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
b = b[n:] b = b[n:]
} }
var num protowire.Number var num protowire.Number
if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) { if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
return out, errors.New("invalid field number") return out, errDecode
} else { } else {
num = protowire.Number(n) num = protowire.Number(n)
} }
@ -114,7 +125,7 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.
if wtyp == protowire.EndGroupType { if wtyp == protowire.EndGroupType {
if num != groupTag { if num != groupTag {
return out, errors.New("mismatching end group marker") return out, errDecode
} }
groupTag = 0 groupTag = 0
break break
@ -170,10 +181,10 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.
} }
n = protowire.ConsumeFieldValue(num, wtyp, b) n = protowire.ConsumeFieldValue(num, wtyp, b)
if n < 0 { if n < 0 {
return out, protowire.ParseError(n) return out, errDecode
} }
if !opts.DiscardUnknown() && mi.unknownOffset.IsValid() { if !opts.DiscardUnknown() && mi.unknownOffset.IsValid() {
u := p.Apply(mi.unknownOffset).Bytes() u := mi.mutableUnknownBytes(p)
*u = protowire.AppendTag(*u, num, wtyp) *u = protowire.AppendTag(*u, num, wtyp)
*u = append(*u, b[:n]...) *u = append(*u, b[:n]...)
} }
@ -181,7 +192,7 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.
b = b[n:] b = b[n:]
} }
if groupTag != 0 { if groupTag != 0 {
return out, errors.New("missing end group marker") return out, errDecode
} }
if mi.numRequiredFields > 0 && bits.OnesCount64(requiredMask) != int(mi.numRequiredFields) { if mi.numRequiredFields > 0 && bits.OnesCount64(requiredMask) != int(mi.numRequiredFields) {
initialized = false initialized = false
@ -200,7 +211,7 @@ func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp p
var err error var err error
xt, err = opts.resolver.FindExtensionByNumber(mi.Desc.FullName(), num) xt, err = opts.resolver.FindExtensionByNumber(mi.Desc.FullName(), num)
if err != nil { if err != nil {
if err == preg.NotFound { if err == protoregistry.NotFound {
return out, errUnknown return out, errUnknown
} }
return out, errors.New("%v: unable to resolve extension %v: %v", mi.Desc.FullName(), num, err) return out, errors.New("%v: unable to resolve extension %v: %v", mi.Desc.FullName(), num, err)
@ -221,7 +232,7 @@ func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp p
return out, nil return out, nil
} }
case ValidationInvalid: case ValidationInvalid:
return out, errors.New("invalid wire format") return out, errDecode
case ValidationUnknown: case ValidationUnknown:
} }
} }

View File

@ -79,8 +79,9 @@ func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int
size += f.funcs.size(fptr, f, opts) size += f.funcs.size(fptr, f, opts)
} }
if mi.unknownOffset.IsValid() { if mi.unknownOffset.IsValid() {
u := *p.Apply(mi.unknownOffset).Bytes() if u := mi.getUnknownBytes(p); u != nil {
size += len(u) size += len(*u)
}
} }
if mi.sizecacheOffset.IsValid() { if mi.sizecacheOffset.IsValid() {
if size > math.MaxInt32 { if size > math.MaxInt32 {
@ -141,8 +142,9 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt
} }
} }
if mi.unknownOffset.IsValid() && !mi.isMessageSet { if mi.unknownOffset.IsValid() && !mi.isMessageSet {
u := *p.Apply(mi.unknownOffset).Bytes() if u := mi.getUnknownBytes(p); u != nil {
b = append(b, u...) b = append(b, (*u)...)
}
} }
return b, nil return b, nil
} }

View File

@ -7,15 +7,15 @@ package impl
import ( import (
"reflect" "reflect"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type EnumInfo struct { type EnumInfo struct {
GoReflectType reflect.Type // int32 kind GoReflectType reflect.Type // int32 kind
Desc pref.EnumDescriptor Desc protoreflect.EnumDescriptor
} }
func (t *EnumInfo) New(n pref.EnumNumber) pref.Enum { func (t *EnumInfo) New(n protoreflect.EnumNumber) protoreflect.Enum {
return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(pref.Enum) return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(protoreflect.Enum)
} }
func (t *EnumInfo) Descriptor() pref.EnumDescriptor { return t.Desc } func (t *EnumInfo) Descriptor() protoreflect.EnumDescriptor { return t.Desc }

View File

@ -9,8 +9,8 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
// ExtensionInfo implements ExtensionType. // ExtensionInfo implements ExtensionType.
@ -45,7 +45,7 @@ type ExtensionInfo struct {
// since the message may no longer implement the MessageV1 interface. // since the message may no longer implement the MessageV1 interface.
// //
// Deprecated: Use the ExtendedType method instead. // Deprecated: Use the ExtendedType method instead.
ExtendedType piface.MessageV1 ExtendedType protoiface.MessageV1
// ExtensionType is the zero value of the extension type. // ExtensionType is the zero value of the extension type.
// //
@ -83,31 +83,31 @@ const (
extensionInfoFullInit = 2 extensionInfoFullInit = 2
) )
func InitExtensionInfo(xi *ExtensionInfo, xd pref.ExtensionDescriptor, goType reflect.Type) { func InitExtensionInfo(xi *ExtensionInfo, xd protoreflect.ExtensionDescriptor, goType reflect.Type) {
xi.goType = goType xi.goType = goType
xi.desc = extensionTypeDescriptor{xd, xi} xi.desc = extensionTypeDescriptor{xd, xi}
xi.init = extensionInfoDescInit xi.init = extensionInfoDescInit
} }
func (xi *ExtensionInfo) New() pref.Value { func (xi *ExtensionInfo) New() protoreflect.Value {
return xi.lazyInit().New() return xi.lazyInit().New()
} }
func (xi *ExtensionInfo) Zero() pref.Value { func (xi *ExtensionInfo) Zero() protoreflect.Value {
return xi.lazyInit().Zero() return xi.lazyInit().Zero()
} }
func (xi *ExtensionInfo) ValueOf(v interface{}) pref.Value { func (xi *ExtensionInfo) ValueOf(v interface{}) protoreflect.Value {
return xi.lazyInit().PBValueOf(reflect.ValueOf(v)) return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
} }
func (xi *ExtensionInfo) InterfaceOf(v pref.Value) interface{} { func (xi *ExtensionInfo) InterfaceOf(v protoreflect.Value) interface{} {
return xi.lazyInit().GoValueOf(v).Interface() return xi.lazyInit().GoValueOf(v).Interface()
} }
func (xi *ExtensionInfo) IsValidValue(v pref.Value) bool { func (xi *ExtensionInfo) IsValidValue(v protoreflect.Value) bool {
return xi.lazyInit().IsValidPB(v) return xi.lazyInit().IsValidPB(v)
} }
func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool { func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
return xi.lazyInit().IsValidGo(reflect.ValueOf(v)) return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
} }
func (xi *ExtensionInfo) TypeDescriptor() pref.ExtensionTypeDescriptor { func (xi *ExtensionInfo) TypeDescriptor() protoreflect.ExtensionTypeDescriptor {
if atomic.LoadUint32(&xi.init) < extensionInfoDescInit { if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
xi.lazyInitSlow() xi.lazyInitSlow()
} }
@ -144,13 +144,13 @@ func (xi *ExtensionInfo) lazyInitSlow() {
} }
type extensionTypeDescriptor struct { type extensionTypeDescriptor struct {
pref.ExtensionDescriptor protoreflect.ExtensionDescriptor
xi *ExtensionInfo xi *ExtensionInfo
} }
func (xtd *extensionTypeDescriptor) Type() pref.ExtensionType { func (xtd *extensionTypeDescriptor) Type() protoreflect.ExtensionType {
return xtd.xi return xtd.xi
} }
func (xtd *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor { func (xtd *extensionTypeDescriptor) Descriptor() protoreflect.ExtensionDescriptor {
return xtd.ExtensionDescriptor return xtd.ExtensionDescriptor
} }

View File

@ -13,13 +13,12 @@ import (
"google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect"
) )
// legacyEnumName returns the name of enums used in legacy code. // legacyEnumName returns the name of enums used in legacy code.
// It is neither the protobuf full name nor the qualified Go name, // It is neither the protobuf full name nor the qualified Go name,
// but rather an odd hybrid of both. // but rather an odd hybrid of both.
func legacyEnumName(ed pref.EnumDescriptor) string { func legacyEnumName(ed protoreflect.EnumDescriptor) string {
var protoPkg string var protoPkg string
enumName := string(ed.FullName()) enumName := string(ed.FullName())
if fd := ed.ParentFile(); fd != nil { if fd := ed.ParentFile(); fd != nil {
@ -34,68 +33,68 @@ func legacyEnumName(ed pref.EnumDescriptor) string {
// legacyWrapEnum wraps v as a protoreflect.Enum, // legacyWrapEnum wraps v as a protoreflect.Enum,
// where v must be a int32 kind and not implement the v2 API already. // where v must be a int32 kind and not implement the v2 API already.
func legacyWrapEnum(v reflect.Value) pref.Enum { func legacyWrapEnum(v reflect.Value) protoreflect.Enum {
et := legacyLoadEnumType(v.Type()) et := legacyLoadEnumType(v.Type())
return et.New(pref.EnumNumber(v.Int())) return et.New(protoreflect.EnumNumber(v.Int()))
} }
var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType
// legacyLoadEnumType dynamically loads a protoreflect.EnumType for t, // legacyLoadEnumType dynamically loads a protoreflect.EnumType for t,
// where t must be an int32 kind and not implement the v2 API already. // where t must be an int32 kind and not implement the v2 API already.
func legacyLoadEnumType(t reflect.Type) pref.EnumType { func legacyLoadEnumType(t reflect.Type) protoreflect.EnumType {
// Fast-path: check if a EnumType is cached for this concrete type. // Fast-path: check if a EnumType is cached for this concrete type.
if et, ok := legacyEnumTypeCache.Load(t); ok { if et, ok := legacyEnumTypeCache.Load(t); ok {
return et.(pref.EnumType) return et.(protoreflect.EnumType)
} }
// Slow-path: derive enum descriptor and initialize EnumType. // Slow-path: derive enum descriptor and initialize EnumType.
var et pref.EnumType var et protoreflect.EnumType
ed := LegacyLoadEnumDesc(t) ed := LegacyLoadEnumDesc(t)
et = &legacyEnumType{ et = &legacyEnumType{
desc: ed, desc: ed,
goType: t, goType: t,
} }
if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok { if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok {
return et.(pref.EnumType) return et.(protoreflect.EnumType)
} }
return et return et
} }
type legacyEnumType struct { type legacyEnumType struct {
desc pref.EnumDescriptor desc protoreflect.EnumDescriptor
goType reflect.Type goType reflect.Type
m sync.Map // map[protoreflect.EnumNumber]proto.Enum m sync.Map // map[protoreflect.EnumNumber]proto.Enum
} }
func (t *legacyEnumType) New(n pref.EnumNumber) pref.Enum { func (t *legacyEnumType) New(n protoreflect.EnumNumber) protoreflect.Enum {
if e, ok := t.m.Load(n); ok { if e, ok := t.m.Load(n); ok {
return e.(pref.Enum) return e.(protoreflect.Enum)
} }
e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType} e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType}
t.m.Store(n, e) t.m.Store(n, e)
return e return e
} }
func (t *legacyEnumType) Descriptor() pref.EnumDescriptor { func (t *legacyEnumType) Descriptor() protoreflect.EnumDescriptor {
return t.desc return t.desc
} }
type legacyEnumWrapper struct { type legacyEnumWrapper struct {
num pref.EnumNumber num protoreflect.EnumNumber
pbTyp pref.EnumType pbTyp protoreflect.EnumType
goTyp reflect.Type goTyp reflect.Type
} }
func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor { func (e *legacyEnumWrapper) Descriptor() protoreflect.EnumDescriptor {
return e.pbTyp.Descriptor() return e.pbTyp.Descriptor()
} }
func (e *legacyEnumWrapper) Type() pref.EnumType { func (e *legacyEnumWrapper) Type() protoreflect.EnumType {
return e.pbTyp return e.pbTyp
} }
func (e *legacyEnumWrapper) Number() pref.EnumNumber { func (e *legacyEnumWrapper) Number() protoreflect.EnumNumber {
return e.num return e.num
} }
func (e *legacyEnumWrapper) ProtoReflect() pref.Enum { func (e *legacyEnumWrapper) ProtoReflect() protoreflect.Enum {
return e return e
} }
func (e *legacyEnumWrapper) protoUnwrap() interface{} { func (e *legacyEnumWrapper) protoUnwrap() interface{} {
@ -105,7 +104,7 @@ func (e *legacyEnumWrapper) protoUnwrap() interface{} {
} }
var ( var (
_ pref.Enum = (*legacyEnumWrapper)(nil) _ protoreflect.Enum = (*legacyEnumWrapper)(nil)
_ unwrapper = (*legacyEnumWrapper)(nil) _ unwrapper = (*legacyEnumWrapper)(nil)
) )
@ -115,15 +114,15 @@ var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
// which must be an int32 kind and not implement the v2 API already. // which must be an int32 kind and not implement the v2 API already.
// //
// This is exported for testing purposes. // This is exported for testing purposes.
func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { func LegacyLoadEnumDesc(t reflect.Type) protoreflect.EnumDescriptor {
// Fast-path: check if an EnumDescriptor is cached for this concrete type. // Fast-path: check if an EnumDescriptor is cached for this concrete type.
if ed, ok := legacyEnumDescCache.Load(t); ok { if ed, ok := legacyEnumDescCache.Load(t); ok {
return ed.(pref.EnumDescriptor) return ed.(protoreflect.EnumDescriptor)
} }
// Slow-path: initialize EnumDescriptor from the raw descriptor. // Slow-path: initialize EnumDescriptor from the raw descriptor.
ev := reflect.Zero(t).Interface() ev := reflect.Zero(t).Interface()
if _, ok := ev.(pref.Enum); ok { if _, ok := ev.(protoreflect.Enum); ok {
panic(fmt.Sprintf("%v already implements proto.Enum", t)) panic(fmt.Sprintf("%v already implements proto.Enum", t))
} }
edV1, ok := ev.(enumV1) edV1, ok := ev.(enumV1)
@ -132,7 +131,7 @@ func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
} }
b, idxs := edV1.EnumDescriptor() b, idxs := edV1.EnumDescriptor()
var ed pref.EnumDescriptor var ed protoreflect.EnumDescriptor
if len(idxs) == 1 { if len(idxs) == 1 {
ed = legacyLoadFileDesc(b).Enums().Get(idxs[0]) ed = legacyLoadFileDesc(b).Enums().Get(idxs[0])
} else { } else {
@ -158,10 +157,10 @@ var aberrantEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescript
// We are unable to use the global enum registry since it is // We are unable to use the global enum registry since it is
// unfortunately keyed by the protobuf full name, which we also do not know. // unfortunately keyed by the protobuf full name, which we also do not know.
// Thus, this produces some bogus enum descriptor based on the Go type name. // Thus, this produces some bogus enum descriptor based on the Go type name.
func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { func aberrantLoadEnumDesc(t reflect.Type) protoreflect.EnumDescriptor {
// Fast-path: check if an EnumDescriptor is cached for this concrete type. // Fast-path: check if an EnumDescriptor is cached for this concrete type.
if ed, ok := aberrantEnumDescCache.Load(t); ok { if ed, ok := aberrantEnumDescCache.Load(t); ok {
return ed.(pref.EnumDescriptor) return ed.(protoreflect.EnumDescriptor)
} }
// Slow-path: construct a bogus, but unique EnumDescriptor. // Slow-path: construct a bogus, but unique EnumDescriptor.
@ -182,7 +181,7 @@ func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
// An exhaustive query is clearly impractical, but can be best-effort. // An exhaustive query is clearly impractical, but can be best-effort.
if ed, ok := aberrantEnumDescCache.LoadOrStore(t, ed); ok { if ed, ok := aberrantEnumDescCache.LoadOrStore(t, ed); ok {
return ed.(pref.EnumDescriptor) return ed.(protoreflect.EnumDescriptor)
} }
return ed return ed
} }
@ -192,7 +191,7 @@ func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
// It should be sufficiently unique within a program. // It should be sufficiently unique within a program.
// //
// This is exported for testing purposes. // This is exported for testing purposes.
func AberrantDeriveFullName(t reflect.Type) pref.FullName { func AberrantDeriveFullName(t reflect.Type) protoreflect.FullName {
sanitize := func(r rune) rune { sanitize := func(r rune) rune {
switch { switch {
case r == '/': case r == '/':
@ -215,5 +214,5 @@ func AberrantDeriveFullName(t reflect.Type) pref.FullName {
ss[i] = "x" + s ss[i] = "x" + s
} }
} }
return pref.FullName(strings.Join(ss, ".")) return protoreflect.FullName(strings.Join(ss, "."))
} }

View File

@ -12,33 +12,33 @@ import (
"reflect" "reflect"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
// These functions exist to support exported APIs in generated protobufs. // These functions exist to support exported APIs in generated protobufs.
// While these are deprecated, they cannot be removed for compatibility reasons. // While these are deprecated, they cannot be removed for compatibility reasons.
// LegacyEnumName returns the name of enums used in legacy code. // LegacyEnumName returns the name of enums used in legacy code.
func (Export) LegacyEnumName(ed pref.EnumDescriptor) string { func (Export) LegacyEnumName(ed protoreflect.EnumDescriptor) string {
return legacyEnumName(ed) return legacyEnumName(ed)
} }
// LegacyMessageTypeOf returns the protoreflect.MessageType for m, // LegacyMessageTypeOf returns the protoreflect.MessageType for m,
// with name used as the message name if necessary. // with name used as the message name if necessary.
func (Export) LegacyMessageTypeOf(m piface.MessageV1, name pref.FullName) pref.MessageType { func (Export) LegacyMessageTypeOf(m protoiface.MessageV1, name protoreflect.FullName) protoreflect.MessageType {
if mv := (Export{}).protoMessageV2Of(m); mv != nil { if mv := (Export{}).protoMessageV2Of(m); mv != nil {
return mv.ProtoReflect().Type() return mv.ProtoReflect().Type()
} }
return legacyLoadMessageInfo(reflect.TypeOf(m), name) return legacyLoadMessageType(reflect.TypeOf(m), name)
} }
// UnmarshalJSONEnum unmarshals an enum from a JSON-encoded input. // UnmarshalJSONEnum unmarshals an enum from a JSON-encoded input.
// The input can either be a string representing the enum value by name, // The input can either be a string representing the enum value by name,
// or a number representing the enum number itself. // or a number representing the enum number itself.
func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumber, error) { func (Export) UnmarshalJSONEnum(ed protoreflect.EnumDescriptor, b []byte) (protoreflect.EnumNumber, error) {
if b[0] == '"' { if b[0] == '"' {
var name pref.Name var name protoreflect.Name
if err := json.Unmarshal(b, &name); err != nil { if err := json.Unmarshal(b, &name); err != nil {
return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b) return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
} }
@ -48,7 +48,7 @@ func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumb
} }
return ev.Number(), nil return ev.Number(), nil
} else { } else {
var num pref.EnumNumber var num protoreflect.EnumNumber
if err := json.Unmarshal(b, &num); err != nil { if err := json.Unmarshal(b, &num); err != nil {
return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b) return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
} }
@ -81,8 +81,8 @@ func (Export) CompressGZIP(in []byte) (out []byte) {
blockHeader[0] = 0x01 // final bit per RFC 1951, section 3.2.3. blockHeader[0] = 0x01 // final bit per RFC 1951, section 3.2.3.
blockSize = len(in) blockSize = len(in)
} }
binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize)^0x0000) binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize))
binary.LittleEndian.PutUint16(blockHeader[3:5], uint16(blockSize)^0xffff) binary.LittleEndian.PutUint16(blockHeader[3:5], ^uint16(blockSize))
out = append(out, blockHeader[:]...) out = append(out, blockHeader[:]...)
out = append(out, in[:blockSize]...) out = append(out, in[:blockSize]...)
in = in[blockSize:] in = in[blockSize:]

View File

@ -12,16 +12,16 @@ import (
ptag "google.golang.org/protobuf/internal/encoding/tag" ptag "google.golang.org/protobuf/internal/encoding/tag"
"google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
func (xi *ExtensionInfo) initToLegacy() { func (xi *ExtensionInfo) initToLegacy() {
xd := xi.desc xd := xi.desc
var parent piface.MessageV1 var parent protoiface.MessageV1
messageName := xd.ContainingMessage().FullName() messageName := xd.ContainingMessage().FullName()
if mt, _ := preg.GlobalTypes.FindMessageByName(messageName); mt != nil { if mt, _ := protoregistry.GlobalTypes.FindMessageByName(messageName); mt != nil {
// Create a new parent message and unwrap it if possible. // Create a new parent message and unwrap it if possible.
mv := mt.New().Interface() mv := mt.New().Interface()
t := reflect.TypeOf(mv) t := reflect.TypeOf(mv)
@ -31,7 +31,7 @@ func (xi *ExtensionInfo) initToLegacy() {
// Check whether the message implements the legacy v1 Message interface. // Check whether the message implements the legacy v1 Message interface.
mz := reflect.Zero(t).Interface() mz := reflect.Zero(t).Interface()
if mz, ok := mz.(piface.MessageV1); ok { if mz, ok := mz.(protoiface.MessageV1); ok {
parent = mz parent = mz
} }
} }
@ -46,7 +46,7 @@ func (xi *ExtensionInfo) initToLegacy() {
// Reconstruct the legacy enum full name. // Reconstruct the legacy enum full name.
var enumName string var enumName string
if xd.Kind() == pref.EnumKind { if xd.Kind() == protoreflect.EnumKind {
enumName = legacyEnumName(xd.Enum()) enumName = legacyEnumName(xd.Enum())
} }
@ -77,16 +77,16 @@ func (xi *ExtensionInfo) initFromLegacy() {
// field number is specified. In such a case, use a placeholder. // field number is specified. In such a case, use a placeholder.
if xi.ExtendedType == nil || xi.ExtensionType == nil { if xi.ExtendedType == nil || xi.ExtensionType == nil {
xd := placeholderExtension{ xd := placeholderExtension{
name: pref.FullName(xi.Name), name: protoreflect.FullName(xi.Name),
number: pref.FieldNumber(xi.Field), number: protoreflect.FieldNumber(xi.Field),
} }
xi.desc = extensionTypeDescriptor{xd, xi} xi.desc = extensionTypeDescriptor{xd, xi}
return return
} }
// Resolve enum or message dependencies. // Resolve enum or message dependencies.
var ed pref.EnumDescriptor var ed protoreflect.EnumDescriptor
var md pref.MessageDescriptor var md protoreflect.MessageDescriptor
t := reflect.TypeOf(xi.ExtensionType) t := reflect.TypeOf(xi.ExtensionType)
isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
@ -94,18 +94,18 @@ func (xi *ExtensionInfo) initFromLegacy() {
t = t.Elem() t = t.Elem()
} }
switch v := reflect.Zero(t).Interface().(type) { switch v := reflect.Zero(t).Interface().(type) {
case pref.Enum: case protoreflect.Enum:
ed = v.Descriptor() ed = v.Descriptor()
case enumV1: case enumV1:
ed = LegacyLoadEnumDesc(t) ed = LegacyLoadEnumDesc(t)
case pref.ProtoMessage: case protoreflect.ProtoMessage:
md = v.ProtoReflect().Descriptor() md = v.ProtoReflect().Descriptor()
case messageV1: case messageV1:
md = LegacyLoadMessageDesc(t) md = LegacyLoadMessageDesc(t)
} }
// Derive basic field information from the struct tag. // Derive basic field information from the struct tag.
var evs pref.EnumValueDescriptors var evs protoreflect.EnumValueDescriptors
if ed != nil { if ed != nil {
evs = ed.Values() evs = ed.Values()
} }
@ -114,8 +114,8 @@ func (xi *ExtensionInfo) initFromLegacy() {
// Construct a v2 ExtensionType. // Construct a v2 ExtensionType.
xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)} xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
xd.L0.ParentFile = filedesc.SurrogateProto2 xd.L0.ParentFile = filedesc.SurrogateProto2
xd.L0.FullName = pref.FullName(xi.Name) xd.L0.FullName = protoreflect.FullName(xi.Name)
xd.L1.Number = pref.FieldNumber(xi.Field) xd.L1.Number = protoreflect.FieldNumber(xi.Field)
xd.L1.Cardinality = fd.L1.Cardinality xd.L1.Cardinality = fd.L1.Cardinality
xd.L1.Kind = fd.L1.Kind xd.L1.Kind = fd.L1.Kind
xd.L2.IsPacked = fd.L1.IsPacked xd.L2.IsPacked = fd.L1.IsPacked
@ -138,23 +138,24 @@ func (xi *ExtensionInfo) initFromLegacy() {
} }
type placeholderExtension struct { type placeholderExtension struct {
name pref.FullName name protoreflect.FullName
number pref.FieldNumber number protoreflect.FieldNumber
} }
func (x placeholderExtension) ParentFile() pref.FileDescriptor { return nil } func (x placeholderExtension) ParentFile() protoreflect.FileDescriptor { return nil }
func (x placeholderExtension) Parent() pref.Descriptor { return nil } func (x placeholderExtension) Parent() protoreflect.Descriptor { return nil }
func (x placeholderExtension) Index() int { return 0 } func (x placeholderExtension) Index() int { return 0 }
func (x placeholderExtension) Syntax() pref.Syntax { return 0 } func (x placeholderExtension) Syntax() protoreflect.Syntax { return 0 }
func (x placeholderExtension) Name() pref.Name { return x.name.Name() } func (x placeholderExtension) Name() protoreflect.Name { return x.name.Name() }
func (x placeholderExtension) FullName() pref.FullName { return x.name } func (x placeholderExtension) FullName() protoreflect.FullName { return x.name }
func (x placeholderExtension) IsPlaceholder() bool { return true } func (x placeholderExtension) IsPlaceholder() bool { return true }
func (x placeholderExtension) Options() pref.ProtoMessage { return descopts.Field } func (x placeholderExtension) Options() protoreflect.ProtoMessage { return descopts.Field }
func (x placeholderExtension) Number() pref.FieldNumber { return x.number } func (x placeholderExtension) Number() protoreflect.FieldNumber { return x.number }
func (x placeholderExtension) Cardinality() pref.Cardinality { return 0 } func (x placeholderExtension) Cardinality() protoreflect.Cardinality { return 0 }
func (x placeholderExtension) Kind() pref.Kind { return 0 } func (x placeholderExtension) Kind() protoreflect.Kind { return 0 }
func (x placeholderExtension) HasJSONName() bool { return false } func (x placeholderExtension) HasJSONName() bool { return false }
func (x placeholderExtension) JSONName() string { return "" } func (x placeholderExtension) JSONName() string { return "[" + string(x.name) + "]" }
func (x placeholderExtension) TextName() string { return "[" + string(x.name) + "]" }
func (x placeholderExtension) HasPresence() bool { return false } func (x placeholderExtension) HasPresence() bool { return false }
func (x placeholderExtension) HasOptionalKeyword() bool { return false } func (x placeholderExtension) HasOptionalKeyword() bool { return false }
func (x placeholderExtension) IsExtension() bool { return true } func (x placeholderExtension) IsExtension() bool { return true }
@ -162,14 +163,14 @@ func (x placeholderExtension) IsWeak() bool { retu
func (x placeholderExtension) IsPacked() bool { return false } func (x placeholderExtension) IsPacked() bool { return false }
func (x placeholderExtension) IsList() bool { return false } func (x placeholderExtension) IsList() bool { return false }
func (x placeholderExtension) IsMap() bool { return false } func (x placeholderExtension) IsMap() bool { return false }
func (x placeholderExtension) MapKey() pref.FieldDescriptor { return nil } func (x placeholderExtension) MapKey() protoreflect.FieldDescriptor { return nil }
func (x placeholderExtension) MapValue() pref.FieldDescriptor { return nil } func (x placeholderExtension) MapValue() protoreflect.FieldDescriptor { return nil }
func (x placeholderExtension) HasDefault() bool { return false } func (x placeholderExtension) HasDefault() bool { return false }
func (x placeholderExtension) Default() pref.Value { return pref.Value{} } func (x placeholderExtension) Default() protoreflect.Value { return protoreflect.Value{} }
func (x placeholderExtension) DefaultEnumValue() pref.EnumValueDescriptor { return nil } func (x placeholderExtension) DefaultEnumValue() protoreflect.EnumValueDescriptor { return nil }
func (x placeholderExtension) ContainingOneof() pref.OneofDescriptor { return nil } func (x placeholderExtension) ContainingOneof() protoreflect.OneofDescriptor { return nil }
func (x placeholderExtension) ContainingMessage() pref.MessageDescriptor { return nil } func (x placeholderExtension) ContainingMessage() protoreflect.MessageDescriptor { return nil }
func (x placeholderExtension) Enum() pref.EnumDescriptor { return nil } func (x placeholderExtension) Enum() protoreflect.EnumDescriptor { return nil }
func (x placeholderExtension) Message() pref.MessageDescriptor { return nil } func (x placeholderExtension) Message() protoreflect.MessageDescriptor { return nil }
func (x placeholderExtension) ProtoType(pref.FieldDescriptor) { return } func (x placeholderExtension) ProtoType(protoreflect.FieldDescriptor) { return }
func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement) { return } func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement) { return }

View File

@ -16,28 +16,36 @@ import (
"google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
piface "google.golang.org/protobuf/runtime/protoiface"
) )
// legacyWrapMessage wraps v as a protoreflect.Message, // legacyWrapMessage wraps v as a protoreflect.Message,
// where v must be a *struct kind and not implement the v2 API already. // where v must be a *struct kind and not implement the v2 API already.
func legacyWrapMessage(v reflect.Value) pref.Message { func legacyWrapMessage(v reflect.Value) protoreflect.Message {
typ := v.Type() t := v.Type()
if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct { if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
return aberrantMessage{v: v} return aberrantMessage{v: v}
} }
mt := legacyLoadMessageInfo(typ, "") mt := legacyLoadMessageInfo(t, "")
return mt.MessageOf(v.Interface()) return mt.MessageOf(v.Interface())
} }
// legacyLoadMessageType dynamically loads a protoreflect.Type for t,
// where t must be not implement the v2 API already.
// The provided name is used if it cannot be determined from the message.
func legacyLoadMessageType(t reflect.Type, name protoreflect.FullName) protoreflect.MessageType {
if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
return aberrantMessageType{t}
}
return legacyLoadMessageInfo(t, name)
}
var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
// legacyLoadMessageInfo dynamically loads a *MessageInfo for t, // legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
// where t must be a *struct kind and not implement the v2 API already. // where t must be a *struct kind and not implement the v2 API already.
// The provided name is used if it cannot be determined from the message. // The provided name is used if it cannot be determined from the message.
func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo { func legacyLoadMessageInfo(t reflect.Type, name protoreflect.FullName) *MessageInfo {
// Fast-path: check if a MessageInfo is cached for this concrete type. // Fast-path: check if a MessageInfo is cached for this concrete type.
if mt, ok := legacyMessageTypeCache.Load(t); ok { if mt, ok := legacyMessageTypeCache.Load(t); ok {
return mt.(*MessageInfo) return mt.(*MessageInfo)
@ -49,20 +57,21 @@ func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo {
GoReflectType: t, GoReflectType: t,
} }
var hasMarshal, hasUnmarshal bool
v := reflect.Zero(t).Interface() v := reflect.Zero(t).Interface()
if _, ok := v.(legacyMarshaler); ok { if _, hasMarshal = v.(legacyMarshaler); hasMarshal {
mi.methods.Marshal = legacyMarshal mi.methods.Marshal = legacyMarshal
// We have no way to tell whether the type's Marshal method // We have no way to tell whether the type's Marshal method
// supports deterministic serialization or not, but this // supports deterministic serialization or not, but this
// preserves the v1 implementation's behavior of always // preserves the v1 implementation's behavior of always
// calling Marshal methods when present. // calling Marshal methods when present.
mi.methods.Flags |= piface.SupportMarshalDeterministic mi.methods.Flags |= protoiface.SupportMarshalDeterministic
} }
if _, ok := v.(legacyUnmarshaler); ok { if _, hasUnmarshal = v.(legacyUnmarshaler); hasUnmarshal {
mi.methods.Unmarshal = legacyUnmarshal mi.methods.Unmarshal = legacyUnmarshal
} }
if _, ok := v.(legacyMerger); ok { if _, hasMerge := v.(legacyMerger); hasMerge || (hasMarshal && hasUnmarshal) {
mi.methods.Merge = legacyMerge mi.methods.Merge = legacyMerge
} }
@ -75,21 +84,21 @@ func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo {
var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor
// LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type, // LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
// which must be a *struct kind and not implement the v2 API already. // which should be a *struct kind and must not implement the v2 API already.
// //
// This is exported for testing purposes. // This is exported for testing purposes.
func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor { func LegacyLoadMessageDesc(t reflect.Type) protoreflect.MessageDescriptor {
return legacyLoadMessageDesc(t, "") return legacyLoadMessageDesc(t, "")
} }
func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor { func legacyLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor {
// Fast-path: check if a MessageDescriptor is cached for this concrete type. // Fast-path: check if a MessageDescriptor is cached for this concrete type.
if mi, ok := legacyMessageDescCache.Load(t); ok { if mi, ok := legacyMessageDescCache.Load(t); ok {
return mi.(pref.MessageDescriptor) return mi.(protoreflect.MessageDescriptor)
} }
// Slow-path: initialize MessageDescriptor from the raw descriptor. // Slow-path: initialize MessageDescriptor from the raw descriptor.
mv := reflect.Zero(t).Interface() mv := reflect.Zero(t).Interface()
if _, ok := mv.(pref.ProtoMessage); ok { if _, ok := mv.(protoreflect.ProtoMessage); ok {
panic(fmt.Sprintf("%v already implements proto.Message", t)) panic(fmt.Sprintf("%v already implements proto.Message", t))
} }
mdV1, ok := mv.(messageV1) mdV1, ok := mv.(messageV1)
@ -114,6 +123,7 @@ func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescr
// If the Go type has no fields, then this might be a proto3 empty message // If the Go type has no fields, then this might be a proto3 empty message
// from before the size cache was added. If there are any fields, check to // from before the size cache was added. If there are any fields, check to
// see that at least one of them looks like something we generated. // see that at least one of them looks like something we generated.
if t.Elem().Kind() == reflect.Struct {
if nfield := t.Elem().NumField(); nfield > 0 { if nfield := t.Elem().NumField(); nfield > 0 {
hasProtoField := false hasProtoField := false
for i := 0; i < nfield; i++ { for i := 0; i < nfield; i++ {
@ -127,6 +137,7 @@ func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescr
return aberrantLoadMessageDesc(t, name) return aberrantLoadMessageDesc(t, name)
} }
} }
}
md := legacyLoadFileDesc(b).Messages().Get(idxs[0]) md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
for _, i := range idxs[1:] { for _, i := range idxs[1:] {
@ -151,7 +162,7 @@ var (
// //
// This is a best-effort derivation of the message descriptor using the protobuf // This is a best-effort derivation of the message descriptor using the protobuf
// tags on the struct fields. // tags on the struct fields.
func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor { func aberrantLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor {
aberrantMessageDescLock.Lock() aberrantMessageDescLock.Lock()
defer aberrantMessageDescLock.Unlock() defer aberrantMessageDescLock.Unlock()
if aberrantMessageDescCache == nil { if aberrantMessageDescCache == nil {
@ -159,7 +170,7 @@ func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDes
} }
return aberrantLoadMessageDescReentrant(t, name) return aberrantLoadMessageDescReentrant(t, name)
} }
func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor { func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor {
// Fast-path: check if an MessageDescriptor is cached for this concrete type. // Fast-path: check if an MessageDescriptor is cached for this concrete type.
if md, ok := aberrantMessageDescCache[t]; ok { if md, ok := aberrantMessageDescCache[t]; ok {
return md return md
@ -212,9 +223,9 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.M
vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0] vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
for i := 0; i < vs.Len(); i++ { for i := 0; i < vs.Len(); i++ {
v := vs.Index(i) v := vs.Index(i)
md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]pref.FieldNumber{ md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{
pref.FieldNumber(v.FieldByName("Start").Int()), protoreflect.FieldNumber(v.FieldByName("Start").Int()),
pref.FieldNumber(v.FieldByName("End").Int() + 1), protoreflect.FieldNumber(v.FieldByName("End").Int() + 1),
}) })
md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil) md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil)
} }
@ -232,7 +243,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.M
n := len(md.L2.Oneofs.List) n := len(md.L2.Oneofs.List)
md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{}) md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{})
od := &md.L2.Oneofs.List[n] od := &md.L2.Oneofs.List[n]
od.L0.FullName = md.FullName().Append(pref.Name(tag)) od.L0.FullName = md.FullName().Append(protoreflect.Name(tag))
od.L0.ParentFile = md.L0.ParentFile od.L0.ParentFile = md.L0.ParentFile
od.L0.Parent = md od.L0.Parent = md
od.L0.Index = n od.L0.Index = n
@ -254,14 +265,14 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.M
return md return md
} }
func aberrantDeriveMessageName(t reflect.Type, name pref.FullName) pref.FullName { func aberrantDeriveMessageName(t reflect.Type, name protoreflect.FullName) protoreflect.FullName {
if name.IsValid() { if name.IsValid() {
return name return name
} }
func() { func() {
defer func() { recover() }() // swallow possible nil panics defer func() { recover() }() // swallow possible nil panics
if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok { if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok {
name = pref.FullName(m.XXX_MessageName()) name = protoreflect.FullName(m.XXX_MessageName())
} }
}() }()
if name.IsValid() { if name.IsValid() {
@ -292,7 +303,7 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey,
fd.L0.Index = n fd.L0.Index = n
if fd.L1.IsWeak || fd.L1.HasPacked { if fd.L1.IsWeak || fd.L1.HasPacked {
fd.L1.Options = func() pref.ProtoMessage { fd.L1.Options = func() protoreflect.ProtoMessage {
opts := descopts.Field.ProtoReflect().New() opts := descopts.Field.ProtoReflect().New()
if fd.L1.IsWeak { if fd.L1.IsWeak {
opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true)) opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
@ -305,17 +316,17 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey,
} }
// Populate Enum and Message. // Populate Enum and Message.
if fd.Enum() == nil && fd.Kind() == pref.EnumKind { if fd.Enum() == nil && fd.Kind() == protoreflect.EnumKind {
switch v := reflect.Zero(t).Interface().(type) { switch v := reflect.Zero(t).Interface().(type) {
case pref.Enum: case protoreflect.Enum:
fd.L1.Enum = v.Descriptor() fd.L1.Enum = v.Descriptor()
default: default:
fd.L1.Enum = LegacyLoadEnumDesc(t) fd.L1.Enum = LegacyLoadEnumDesc(t)
} }
} }
if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) { if fd.Message() == nil && (fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind) {
switch v := reflect.Zero(t).Interface().(type) { switch v := reflect.Zero(t).Interface().(type) {
case pref.ProtoMessage: case protoreflect.ProtoMessage:
fd.L1.Message = v.ProtoReflect().Descriptor() fd.L1.Message = v.ProtoReflect().Descriptor()
case messageV1: case messageV1:
fd.L1.Message = LegacyLoadMessageDesc(t) fd.L1.Message = LegacyLoadMessageDesc(t)
@ -324,13 +335,13 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey,
n := len(md.L1.Messages.List) n := len(md.L1.Messages.List)
md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)}) md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)})
md2 := &md.L1.Messages.List[n] md2 := &md.L1.Messages.List[n]
md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name())))) md2.L0.FullName = md.FullName().Append(protoreflect.Name(strs.MapEntryName(string(fd.Name()))))
md2.L0.ParentFile = md.L0.ParentFile md2.L0.ParentFile = md.L0.ParentFile
md2.L0.Parent = md md2.L0.Parent = md
md2.L0.Index = n md2.L0.Index = n
md2.L1.IsMapEntry = true md2.L1.IsMapEntry = true
md2.L2.Options = func() pref.ProtoMessage { md2.L2.Options = func() protoreflect.ProtoMessage {
opts := descopts.Message.ProtoReflect().New() opts := descopts.Message.ProtoReflect().New()
opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true)) opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
return opts.Interface() return opts.Interface()
@ -351,8 +362,8 @@ type placeholderEnumValues struct {
protoreflect.EnumValueDescriptors protoreflect.EnumValueDescriptors
} }
func (placeholderEnumValues) ByNumber(n pref.EnumNumber) pref.EnumValueDescriptor { func (placeholderEnumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor {
return filedesc.PlaceholderEnumValue(pref.FullName(fmt.Sprintf("UNKNOWN_%d", n))) return filedesc.PlaceholderEnumValue(protoreflect.FullName(fmt.Sprintf("UNKNOWN_%d", n)))
} }
// legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder. // legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder.
@ -370,7 +381,7 @@ type legacyMerger interface {
Merge(protoiface.MessageV1) Merge(protoiface.MessageV1)
} }
var legacyProtoMethods = &piface.Methods{ var aberrantProtoMethods = &protoiface.Methods{
Marshal: legacyMarshal, Marshal: legacyMarshal,
Unmarshal: legacyUnmarshal, Unmarshal: legacyUnmarshal,
Merge: legacyMerge, Merge: legacyMerge,
@ -379,41 +390,70 @@ var legacyProtoMethods = &piface.Methods{
// supports deterministic serialization or not, but this // supports deterministic serialization or not, but this
// preserves the v1 implementation's behavior of always // preserves the v1 implementation's behavior of always
// calling Marshal methods when present. // calling Marshal methods when present.
Flags: piface.SupportMarshalDeterministic, Flags: protoiface.SupportMarshalDeterministic,
} }
func legacyMarshal(in piface.MarshalInput) (piface.MarshalOutput, error) { func legacyMarshal(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
v := in.Message.(unwrapper).protoUnwrap() v := in.Message.(unwrapper).protoUnwrap()
marshaler, ok := v.(legacyMarshaler) marshaler, ok := v.(legacyMarshaler)
if !ok { if !ok {
return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v) return protoiface.MarshalOutput{}, errors.New("%T does not implement Marshal", v)
} }
out, err := marshaler.Marshal() out, err := marshaler.Marshal()
if in.Buf != nil { if in.Buf != nil {
out = append(in.Buf, out...) out = append(in.Buf, out...)
} }
return piface.MarshalOutput{ return protoiface.MarshalOutput{
Buf: out, Buf: out,
}, err }, err
} }
func legacyUnmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) { func legacyUnmarshal(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
v := in.Message.(unwrapper).protoUnwrap() v := in.Message.(unwrapper).protoUnwrap()
unmarshaler, ok := v.(legacyUnmarshaler) unmarshaler, ok := v.(legacyUnmarshaler)
if !ok { if !ok {
return piface.UnmarshalOutput{}, errors.New("%T does not implement Marshal", v) return protoiface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v)
} }
return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf) return protoiface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
} }
func legacyMerge(in piface.MergeInput) piface.MergeOutput { func legacyMerge(in protoiface.MergeInput) protoiface.MergeOutput {
// Check whether this supports the legacy merger.
dstv := in.Destination.(unwrapper).protoUnwrap() dstv := in.Destination.(unwrapper).protoUnwrap()
merger, ok := dstv.(legacyMerger) merger, ok := dstv.(legacyMerger)
if !ok { if ok {
return piface.MergeOutput{}
}
merger.Merge(Export{}.ProtoMessageV1Of(in.Source)) merger.Merge(Export{}.ProtoMessageV1Of(in.Source))
return piface.MergeOutput{Flags: piface.MergeComplete} return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
}
// If legacy merger is unavailable, implement merge in terms of
// a marshal and unmarshal operation.
srcv := in.Source.(unwrapper).protoUnwrap()
marshaler, ok := srcv.(legacyMarshaler)
if !ok {
return protoiface.MergeOutput{}
}
dstv = in.Destination.(unwrapper).protoUnwrap()
unmarshaler, ok := dstv.(legacyUnmarshaler)
if !ok {
return protoiface.MergeOutput{}
}
if !in.Source.IsValid() {
// Legacy Marshal methods may not function on nil messages.
// Check for a typed nil source only after we confirm that
// legacy Marshal/Unmarshal methods are present, for
// consistency.
return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
}
b, err := marshaler.Marshal()
if err != nil {
return protoiface.MergeOutput{}
}
err = unmarshaler.Unmarshal(b)
if err != nil {
return protoiface.MergeOutput{}
}
return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
} }
// aberrantMessageType implements MessageType for all types other than pointer-to-struct. // aberrantMessageType implements MessageType for all types other than pointer-to-struct.
@ -421,16 +461,19 @@ type aberrantMessageType struct {
t reflect.Type t reflect.Type
} }
func (mt aberrantMessageType) New() pref.Message { func (mt aberrantMessageType) New() protoreflect.Message {
if mt.t.Kind() == reflect.Ptr {
return aberrantMessage{reflect.New(mt.t.Elem())}
}
return aberrantMessage{reflect.Zero(mt.t)} return aberrantMessage{reflect.Zero(mt.t)}
} }
func (mt aberrantMessageType) Zero() pref.Message { func (mt aberrantMessageType) Zero() protoreflect.Message {
return aberrantMessage{reflect.Zero(mt.t)} return aberrantMessage{reflect.Zero(mt.t)}
} }
func (mt aberrantMessageType) GoType() reflect.Type { func (mt aberrantMessageType) GoType() reflect.Type {
return mt.t return mt.t
} }
func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor { func (mt aberrantMessageType) Descriptor() protoreflect.MessageDescriptor {
return LegacyLoadMessageDesc(mt.t) return LegacyLoadMessageDesc(mt.t)
} }
@ -443,59 +486,77 @@ type aberrantMessage struct {
v reflect.Value v reflect.Value
} }
func (m aberrantMessage) ProtoReflect() pref.Message { // Reset implements the v1 proto.Message.Reset method.
func (m aberrantMessage) Reset() {
if mr, ok := m.v.Interface().(interface{ Reset() }); ok {
mr.Reset()
return
}
if m.v.Kind() == reflect.Ptr && !m.v.IsNil() {
m.v.Elem().Set(reflect.Zero(m.v.Type().Elem()))
}
}
func (m aberrantMessage) ProtoReflect() protoreflect.Message {
return m return m
} }
func (m aberrantMessage) Descriptor() pref.MessageDescriptor { func (m aberrantMessage) Descriptor() protoreflect.MessageDescriptor {
return LegacyLoadMessageDesc(m.v.Type()) return LegacyLoadMessageDesc(m.v.Type())
} }
func (m aberrantMessage) Type() pref.MessageType { func (m aberrantMessage) Type() protoreflect.MessageType {
return aberrantMessageType{m.v.Type()} return aberrantMessageType{m.v.Type()}
} }
func (m aberrantMessage) New() pref.Message { func (m aberrantMessage) New() protoreflect.Message {
if m.v.Type().Kind() == reflect.Ptr {
return aberrantMessage{reflect.New(m.v.Type().Elem())}
}
return aberrantMessage{reflect.Zero(m.v.Type())} return aberrantMessage{reflect.Zero(m.v.Type())}
} }
func (m aberrantMessage) Interface() pref.ProtoMessage { func (m aberrantMessage) Interface() protoreflect.ProtoMessage {
return m return m
} }
func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) { func (m aberrantMessage) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
return
} }
func (m aberrantMessage) Has(pref.FieldDescriptor) bool { func (m aberrantMessage) Has(protoreflect.FieldDescriptor) bool {
panic("invalid field descriptor") return false
} }
func (m aberrantMessage) Clear(pref.FieldDescriptor) { func (m aberrantMessage) Clear(protoreflect.FieldDescriptor) {
panic("invalid field descriptor") panic("invalid Message.Clear on " + string(m.Descriptor().FullName()))
} }
func (m aberrantMessage) Get(pref.FieldDescriptor) pref.Value { func (m aberrantMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
panic("invalid field descriptor") if fd.Default().IsValid() {
return fd.Default()
}
panic("invalid Message.Get on " + string(m.Descriptor().FullName()))
} }
func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) { func (m aberrantMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) {
panic("invalid field descriptor") panic("invalid Message.Set on " + string(m.Descriptor().FullName()))
} }
func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value { func (m aberrantMessage) Mutable(protoreflect.FieldDescriptor) protoreflect.Value {
panic("invalid field descriptor") panic("invalid Message.Mutable on " + string(m.Descriptor().FullName()))
} }
func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value { func (m aberrantMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value {
panic("invalid field descriptor") panic("invalid Message.NewField on " + string(m.Descriptor().FullName()))
} }
func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor { func (m aberrantMessage) WhichOneof(protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
panic("invalid oneof descriptor") panic("invalid Message.WhichOneof descriptor on " + string(m.Descriptor().FullName()))
} }
func (m aberrantMessage) GetUnknown() pref.RawFields { func (m aberrantMessage) GetUnknown() protoreflect.RawFields {
return nil return nil
} }
func (m aberrantMessage) SetUnknown(pref.RawFields) { func (m aberrantMessage) SetUnknown(protoreflect.RawFields) {
// SetUnknown discards its input on messages which don't support unknown field storage. // SetUnknown discards its input on messages which don't support unknown field storage.
} }
func (m aberrantMessage) IsValid() bool { func (m aberrantMessage) IsValid() bool {
// An invalid message is a read-only, empty message. Since we don't know anything if m.v.Kind() == reflect.Ptr {
// about the alleged contents of this message, we can't say with confidence that return !m.v.IsNil()
// it is invalid in this sense. Therefore, report it as valid. }
return true return false
} }
func (m aberrantMessage) ProtoMethods() *piface.Methods { func (m aberrantMessage) ProtoMethods() *protoiface.Methods {
return legacyProtoMethods return aberrantProtoMethods
} }
func (m aberrantMessage) protoUnwrap() interface{} { func (m aberrantMessage) protoUnwrap() interface{} {
return m.v.Interface() return m.v.Interface()

View File

@ -9,8 +9,8 @@ import (
"reflect" "reflect"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
type mergeOptions struct{} type mergeOptions struct{}
@ -20,17 +20,17 @@ func (o mergeOptions) Merge(dst, src proto.Message) {
} }
// merge is protoreflect.Methods.Merge. // merge is protoreflect.Methods.Merge.
func (mi *MessageInfo) merge(in piface.MergeInput) piface.MergeOutput { func (mi *MessageInfo) merge(in protoiface.MergeInput) protoiface.MergeOutput {
dp, ok := mi.getPointer(in.Destination) dp, ok := mi.getPointer(in.Destination)
if !ok { if !ok {
return piface.MergeOutput{} return protoiface.MergeOutput{}
} }
sp, ok := mi.getPointer(in.Source) sp, ok := mi.getPointer(in.Source)
if !ok { if !ok {
return piface.MergeOutput{} return protoiface.MergeOutput{}
} }
mi.mergePointer(dp, sp, mergeOptions{}) mi.mergePointer(dp, sp, mergeOptions{})
return piface.MergeOutput{Flags: piface.MergeComplete} return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
} }
func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) { func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
@ -64,7 +64,7 @@ func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
continue continue
} }
dx := (*dext)[num] dx := (*dext)[num]
var dv pref.Value var dv protoreflect.Value
if dx.Type() == sx.Type() { if dx.Type() == sx.Type() {
dv = dx.Value() dv = dx.Value()
} }
@ -77,23 +77,23 @@ func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
} }
} }
if mi.unknownOffset.IsValid() { if mi.unknownOffset.IsValid() {
du := dst.Apply(mi.unknownOffset).Bytes() su := mi.getUnknownBytes(src)
su := src.Apply(mi.unknownOffset).Bytes() if su != nil && len(*su) > 0 {
if len(*su) > 0 { du := mi.mutableUnknownBytes(dst)
*du = append(*du, *su...) *du = append(*du, *su...)
} }
} }
} }
func mergeScalarValue(dst, src pref.Value, opts mergeOptions) pref.Value { func mergeScalarValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
return src return src
} }
func mergeBytesValue(dst, src pref.Value, opts mergeOptions) pref.Value { func mergeBytesValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
return pref.ValueOfBytes(append(emptyBuf[:], src.Bytes()...)) return protoreflect.ValueOfBytes(append(emptyBuf[:], src.Bytes()...))
} }
func mergeListValue(dst, src pref.Value, opts mergeOptions) pref.Value { func mergeListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
dstl := dst.List() dstl := dst.List()
srcl := src.List() srcl := src.List()
for i, llen := 0, srcl.Len(); i < llen; i++ { for i, llen := 0, srcl.Len(); i < llen; i++ {
@ -102,29 +102,29 @@ func mergeListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
return dst return dst
} }
func mergeBytesListValue(dst, src pref.Value, opts mergeOptions) pref.Value { func mergeBytesListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
dstl := dst.List() dstl := dst.List()
srcl := src.List() srcl := src.List()
for i, llen := 0, srcl.Len(); i < llen; i++ { for i, llen := 0, srcl.Len(); i < llen; i++ {
sb := srcl.Get(i).Bytes() sb := srcl.Get(i).Bytes()
db := append(emptyBuf[:], sb...) db := append(emptyBuf[:], sb...)
dstl.Append(pref.ValueOfBytes(db)) dstl.Append(protoreflect.ValueOfBytes(db))
} }
return dst return dst
} }
func mergeMessageListValue(dst, src pref.Value, opts mergeOptions) pref.Value { func mergeMessageListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
dstl := dst.List() dstl := dst.List()
srcl := src.List() srcl := src.List()
for i, llen := 0, srcl.Len(); i < llen; i++ { for i, llen := 0, srcl.Len(); i < llen; i++ {
sm := srcl.Get(i).Message() sm := srcl.Get(i).Message()
dm := proto.Clone(sm.Interface()).ProtoReflect() dm := proto.Clone(sm.Interface()).ProtoReflect()
dstl.Append(pref.ValueOfMessage(dm)) dstl.Append(protoreflect.ValueOfMessage(dm))
} }
return dst return dst
} }
func mergeMessageValue(dst, src pref.Value, opts mergeOptions) pref.Value { func mergeMessageValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
opts.Merge(dst.Message().Interface(), src.Message().Interface()) opts.Merge(dst.Message().Interface(), src.Message().Interface())
return dst return dst
} }

View File

@ -14,7 +14,7 @@ import (
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry"
) )
// MessageInfo provides protobuf related functionality for a given Go type // MessageInfo provides protobuf related functionality for a given Go type
@ -28,7 +28,7 @@ type MessageInfo struct {
GoReflectType reflect.Type // pointer to struct GoReflectType reflect.Type // pointer to struct
// Desc is the underlying message descriptor type and must be populated. // Desc is the underlying message descriptor type and must be populated.
Desc pref.MessageDescriptor Desc protoreflect.MessageDescriptor
// Exporter must be provided in a purego environment in order to provide // Exporter must be provided in a purego environment in order to provide
// access to unexported fields. // access to unexported fields.
@ -53,7 +53,7 @@ type exporter func(v interface{}, i int) interface{}
// is generated by our implementation of protoc-gen-go (for v2 and on). // is generated by our implementation of protoc-gen-go (for v2 and on).
// If it is unable to obtain a MessageInfo, it returns nil. // If it is unable to obtain a MessageInfo, it returns nil.
func getMessageInfo(mt reflect.Type) *MessageInfo { func getMessageInfo(mt reflect.Type) *MessageInfo {
m, ok := reflect.Zero(mt).Interface().(pref.ProtoMessage) m, ok := reflect.Zero(mt).Interface().(protoreflect.ProtoMessage)
if !ok { if !ok {
return nil return nil
} }
@ -96,7 +96,7 @@ func (mi *MessageInfo) initOnce() {
// getPointer returns the pointer for a message, which should be of // getPointer returns the pointer for a message, which should be of
// the type of the MessageInfo. If the message is of a different type, // the type of the MessageInfo. If the message is of a different type,
// it returns ok==false. // it returns ok==false.
func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) { func (mi *MessageInfo) getPointer(m protoreflect.Message) (p pointer, ok bool) {
switch m := m.(type) { switch m := m.(type) {
case *messageState: case *messageState:
return m.pointer(), m.messageInfo() == mi return m.pointer(), m.messageInfo() == mi
@ -109,27 +109,34 @@ func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) {
type ( type (
SizeCache = int32 SizeCache = int32
WeakFields = map[int32]protoreflect.ProtoMessage WeakFields = map[int32]protoreflect.ProtoMessage
UnknownFields = []byte UnknownFields = unknownFieldsA // TODO: switch to unknownFieldsB
unknownFieldsA = []byte
unknownFieldsB = *[]byte
ExtensionFields = map[int32]ExtensionField ExtensionFields = map[int32]ExtensionField
) )
var ( var (
sizecacheType = reflect.TypeOf(SizeCache(0)) sizecacheType = reflect.TypeOf(SizeCache(0))
weakFieldsType = reflect.TypeOf(WeakFields(nil)) weakFieldsType = reflect.TypeOf(WeakFields(nil))
unknownFieldsType = reflect.TypeOf(UnknownFields(nil)) unknownFieldsAType = reflect.TypeOf(unknownFieldsA(nil))
unknownFieldsBType = reflect.TypeOf(unknownFieldsB(nil))
extensionFieldsType = reflect.TypeOf(ExtensionFields(nil)) extensionFieldsType = reflect.TypeOf(ExtensionFields(nil))
) )
type structInfo struct { type structInfo struct {
sizecacheOffset offset sizecacheOffset offset
sizecacheType reflect.Type
weakOffset offset weakOffset offset
weakType reflect.Type
unknownOffset offset unknownOffset offset
unknownType reflect.Type
extensionOffset offset extensionOffset offset
extensionType reflect.Type
fieldsByNumber map[pref.FieldNumber]reflect.StructField fieldsByNumber map[protoreflect.FieldNumber]reflect.StructField
oneofsByName map[pref.Name]reflect.StructField oneofsByName map[protoreflect.Name]reflect.StructField
oneofWrappersByType map[reflect.Type]pref.FieldNumber oneofWrappersByType map[reflect.Type]protoreflect.FieldNumber
oneofWrappersByNumber map[pref.FieldNumber]reflect.Type oneofWrappersByNumber map[protoreflect.FieldNumber]reflect.Type
} }
func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo { func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo {
@ -139,10 +146,10 @@ func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo {
unknownOffset: invalidOffset, unknownOffset: invalidOffset,
extensionOffset: invalidOffset, extensionOffset: invalidOffset,
fieldsByNumber: map[pref.FieldNumber]reflect.StructField{}, fieldsByNumber: map[protoreflect.FieldNumber]reflect.StructField{},
oneofsByName: map[pref.Name]reflect.StructField{}, oneofsByName: map[protoreflect.Name]reflect.StructField{},
oneofWrappersByType: map[reflect.Type]pref.FieldNumber{}, oneofWrappersByType: map[reflect.Type]protoreflect.FieldNumber{},
oneofWrappersByNumber: map[pref.FieldNumber]reflect.Type{}, oneofWrappersByNumber: map[protoreflect.FieldNumber]reflect.Type{},
} }
fieldLoop: fieldLoop:
@ -151,29 +158,33 @@ fieldLoop:
case genid.SizeCache_goname, genid.SizeCacheA_goname: case genid.SizeCache_goname, genid.SizeCacheA_goname:
if f.Type == sizecacheType { if f.Type == sizecacheType {
si.sizecacheOffset = offsetOf(f, mi.Exporter) si.sizecacheOffset = offsetOf(f, mi.Exporter)
si.sizecacheType = f.Type
} }
case genid.WeakFields_goname, genid.WeakFieldsA_goname: case genid.WeakFields_goname, genid.WeakFieldsA_goname:
if f.Type == weakFieldsType { if f.Type == weakFieldsType {
si.weakOffset = offsetOf(f, mi.Exporter) si.weakOffset = offsetOf(f, mi.Exporter)
si.weakType = f.Type
} }
case genid.UnknownFields_goname, genid.UnknownFieldsA_goname: case genid.UnknownFields_goname, genid.UnknownFieldsA_goname:
if f.Type == unknownFieldsType { if f.Type == unknownFieldsAType || f.Type == unknownFieldsBType {
si.unknownOffset = offsetOf(f, mi.Exporter) si.unknownOffset = offsetOf(f, mi.Exporter)
si.unknownType = f.Type
} }
case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname: case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname:
if f.Type == extensionFieldsType { if f.Type == extensionFieldsType {
si.extensionOffset = offsetOf(f, mi.Exporter) si.extensionOffset = offsetOf(f, mi.Exporter)
si.extensionType = f.Type
} }
default: default:
for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
if len(s) > 0 && strings.Trim(s, "0123456789") == "" { if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
n, _ := strconv.ParseUint(s, 10, 64) n, _ := strconv.ParseUint(s, 10, 64)
si.fieldsByNumber[pref.FieldNumber(n)] = f si.fieldsByNumber[protoreflect.FieldNumber(n)] = f
continue fieldLoop continue fieldLoop
} }
} }
if s := f.Tag.Get("protobuf_oneof"); len(s) > 0 { if s := f.Tag.Get("protobuf_oneof"); len(s) > 0 {
si.oneofsByName[pref.Name(s)] = f si.oneofsByName[protoreflect.Name(s)] = f
continue fieldLoop continue fieldLoop
} }
} }
@ -196,8 +207,8 @@ fieldLoop:
for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
if len(s) > 0 && strings.Trim(s, "0123456789") == "" { if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
n, _ := strconv.ParseUint(s, 10, 64) n, _ := strconv.ParseUint(s, 10, 64)
si.oneofWrappersByType[tf] = pref.FieldNumber(n) si.oneofWrappersByType[tf] = protoreflect.FieldNumber(n)
si.oneofWrappersByNumber[pref.FieldNumber(n)] = tf si.oneofWrappersByNumber[protoreflect.FieldNumber(n)] = tf
break break
} }
} }
@ -207,9 +218,62 @@ fieldLoop:
} }
func (mi *MessageInfo) New() protoreflect.Message { func (mi *MessageInfo) New() protoreflect.Message {
return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface()) m := reflect.New(mi.GoReflectType.Elem()).Interface()
if r, ok := m.(protoreflect.ProtoMessage); ok {
return r.ProtoReflect()
}
return mi.MessageOf(m)
} }
func (mi *MessageInfo) Zero() protoreflect.Message { func (mi *MessageInfo) Zero() protoreflect.Message {
return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface()) return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface())
} }
func (mi *MessageInfo) Descriptor() protoreflect.MessageDescriptor { return mi.Desc } func (mi *MessageInfo) Descriptor() protoreflect.MessageDescriptor {
return mi.Desc
}
func (mi *MessageInfo) Enum(i int) protoreflect.EnumType {
mi.init()
fd := mi.Desc.Fields().Get(i)
return Export{}.EnumTypeOf(mi.fieldTypes[fd.Number()])
}
func (mi *MessageInfo) Message(i int) protoreflect.MessageType {
mi.init()
fd := mi.Desc.Fields().Get(i)
switch {
case fd.IsWeak():
mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName())
return mt
case fd.IsMap():
return mapEntryType{fd.Message(), mi.fieldTypes[fd.Number()]}
default:
return Export{}.MessageTypeOf(mi.fieldTypes[fd.Number()])
}
}
type mapEntryType struct {
desc protoreflect.MessageDescriptor
valType interface{} // zero value of enum or message type
}
func (mt mapEntryType) New() protoreflect.Message {
return nil
}
func (mt mapEntryType) Zero() protoreflect.Message {
return nil
}
func (mt mapEntryType) Descriptor() protoreflect.MessageDescriptor {
return mt.desc
}
func (mt mapEntryType) Enum(i int) protoreflect.EnumType {
fd := mt.desc.Fields().Get(i)
if fd.Enum() == nil {
return nil
}
return Export{}.EnumTypeOf(mt.valType)
}
func (mt mapEntryType) Message(i int) protoreflect.MessageType {
fd := mt.desc.Fields().Get(i)
if fd.Message() == nil {
return nil
}
return Export{}.MessageTypeOf(mt.valType)
}

View File

@ -8,13 +8,19 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"google.golang.org/protobuf/internal/detrand"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type reflectMessageInfo struct { type reflectMessageInfo struct {
fields map[pref.FieldNumber]*fieldInfo fields map[protoreflect.FieldNumber]*fieldInfo
oneofs map[pref.Name]*oneofInfo oneofs map[protoreflect.Name]*oneofInfo
// fieldTypes contains the zero value of an enum or message field.
// For lists, it contains the element type.
// For maps, it contains the entry value type.
fieldTypes map[protoreflect.FieldNumber]interface{}
// denseFields is a subset of fields where: // denseFields is a subset of fields where:
// 0 < fieldDesc.Number() < len(denseFields) // 0 < fieldDesc.Number() < len(denseFields)
@ -24,8 +30,8 @@ type reflectMessageInfo struct {
// rangeInfos is a list of all fields (not belonging to a oneof) and oneofs. // rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
rangeInfos []interface{} // either *fieldInfo or *oneofInfo rangeInfos []interface{} // either *fieldInfo or *oneofInfo
getUnknown func(pointer) pref.RawFields getUnknown func(pointer) protoreflect.RawFields
setUnknown func(pointer, pref.RawFields) setUnknown func(pointer, protoreflect.RawFields)
extensionMap func(pointer) *extensionMap extensionMap func(pointer) *extensionMap
nilMessage atomicNilMessage nilMessage atomicNilMessage
@ -36,6 +42,7 @@ func (mi *MessageInfo) makeReflectFuncs(t reflect.Type, si structInfo) {
mi.makeKnownFieldsFunc(si) mi.makeKnownFieldsFunc(si)
mi.makeUnknownFieldsFunc(t, si) mi.makeUnknownFieldsFunc(t, si)
mi.makeExtensionFieldsFunc(t, si) mi.makeExtensionFieldsFunc(t, si)
mi.makeFieldTypes(si)
} }
// makeKnownFieldsFunc generates functions for operations that can be performed // makeKnownFieldsFunc generates functions for operations that can be performed
@ -45,23 +52,29 @@ func (mi *MessageInfo) makeReflectFuncs(t reflect.Type, si structInfo) {
// This code assumes that the struct is well-formed and panics if there are // This code assumes that the struct is well-formed and panics if there are
// any discrepancies. // any discrepancies.
func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) { func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
mi.fields = map[pref.FieldNumber]*fieldInfo{} mi.fields = map[protoreflect.FieldNumber]*fieldInfo{}
md := mi.Desc md := mi.Desc
fds := md.Fields() fds := md.Fields()
for i := 0; i < fds.Len(); i++ { for i := 0; i < fds.Len(); i++ {
fd := fds.Get(i) fd := fds.Get(i)
fs := si.fieldsByNumber[fd.Number()] fs := si.fieldsByNumber[fd.Number()]
isOneof := fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic()
if isOneof {
fs = si.oneofsByName[fd.ContainingOneof().Name()]
}
var fi fieldInfo var fi fieldInfo
switch { switch {
case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): case fs.Type == nil:
fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()]) fi = fieldInfoForMissing(fd) // never occurs for officially generated message types
case isOneof:
fi = fieldInfoForOneof(fd, fs, mi.Exporter, si.oneofWrappersByNumber[fd.Number()])
case fd.IsMap(): case fd.IsMap():
fi = fieldInfoForMap(fd, fs, mi.Exporter) fi = fieldInfoForMap(fd, fs, mi.Exporter)
case fd.IsList(): case fd.IsList():
fi = fieldInfoForList(fd, fs, mi.Exporter) fi = fieldInfoForList(fd, fs, mi.Exporter)
case fd.IsWeak(): case fd.IsWeak():
fi = fieldInfoForWeakMessage(fd, si.weakOffset) fi = fieldInfoForWeakMessage(fd, si.weakOffset)
case fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind: case fd.Message() != nil:
fi = fieldInfoForMessage(fd, fs, mi.Exporter) fi = fieldInfoForMessage(fd, fs, mi.Exporter)
default: default:
fi = fieldInfoForScalar(fd, fs, mi.Exporter) fi = fieldInfoForScalar(fd, fs, mi.Exporter)
@ -69,7 +82,7 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
mi.fields[fd.Number()] = &fi mi.fields[fd.Number()] = &fi
} }
mi.oneofs = map[pref.Name]*oneofInfo{} mi.oneofs = map[protoreflect.Name]*oneofInfo{}
for i := 0; i < md.Oneofs().Len(); i++ { for i := 0; i < md.Oneofs().Len(); i++ {
od := md.Oneofs().Get(i) od := md.Oneofs().Get(i)
mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter) mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter)
@ -92,31 +105,57 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
i++ i++
} }
} }
// Introduce instability to iteration order, but keep it deterministic.
if len(mi.rangeInfos) > 1 && detrand.Bool() {
i := detrand.Intn(len(mi.rangeInfos) - 1)
mi.rangeInfos[i], mi.rangeInfos[i+1] = mi.rangeInfos[i+1], mi.rangeInfos[i]
}
} }
func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {
mi.getUnknown = func(pointer) pref.RawFields { return nil } switch {
mi.setUnknown = func(pointer, pref.RawFields) { return } case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsAType:
if si.unknownOffset.IsValid() { // Handle as []byte.
mi.getUnknown = func(p pointer) pref.RawFields { mi.getUnknown = func(p pointer) protoreflect.RawFields {
if p.IsNil() { if p.IsNil() {
return nil return nil
} }
rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType) return *p.Apply(mi.unknownOffset).Bytes()
return pref.RawFields(*rv.Interface().(*[]byte))
} }
mi.setUnknown = func(p pointer, b pref.RawFields) { mi.setUnknown = func(p pointer, b protoreflect.RawFields) {
if p.IsNil() { if p.IsNil() {
panic("invalid SetUnknown on nil Message") panic("invalid SetUnknown on nil Message")
} }
rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType) *p.Apply(mi.unknownOffset).Bytes() = b
*rv.Interface().(*[]byte) = []byte(b)
} }
} else { case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsBType:
mi.getUnknown = func(pointer) pref.RawFields { // Handle as *[]byte.
mi.getUnknown = func(p pointer) protoreflect.RawFields {
if p.IsNil() {
return nil return nil
} }
mi.setUnknown = func(p pointer, _ pref.RawFields) { bp := p.Apply(mi.unknownOffset).BytesPtr()
if *bp == nil {
return nil
}
return **bp
}
mi.setUnknown = func(p pointer, b protoreflect.RawFields) {
if p.IsNil() {
panic("invalid SetUnknown on nil Message")
}
bp := p.Apply(mi.unknownOffset).BytesPtr()
if *bp == nil {
*bp = new([]byte)
}
**bp = b
}
default:
mi.getUnknown = func(pointer) protoreflect.RawFields {
return nil
}
mi.setUnknown = func(p pointer, _ protoreflect.RawFields) {
if p.IsNil() { if p.IsNil() {
panic("invalid SetUnknown on nil Message") panic("invalid SetUnknown on nil Message")
} }
@ -139,10 +178,62 @@ func (mi *MessageInfo) makeExtensionFieldsFunc(t reflect.Type, si structInfo) {
} }
} }
} }
func (mi *MessageInfo) makeFieldTypes(si structInfo) {
md := mi.Desc
fds := md.Fields()
for i := 0; i < fds.Len(); i++ {
var ft reflect.Type
fd := fds.Get(i)
fs := si.fieldsByNumber[fd.Number()]
isOneof := fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic()
if isOneof {
fs = si.oneofsByName[fd.ContainingOneof().Name()]
}
var isMessage bool
switch {
case fs.Type == nil:
continue // never occurs for officially generated message types
case isOneof:
if fd.Enum() != nil || fd.Message() != nil {
ft = si.oneofWrappersByNumber[fd.Number()].Field(0).Type
}
case fd.IsMap():
if fd.MapValue().Enum() != nil || fd.MapValue().Message() != nil {
ft = fs.Type.Elem()
}
isMessage = fd.MapValue().Message() != nil
case fd.IsList():
if fd.Enum() != nil || fd.Message() != nil {
ft = fs.Type.Elem()
}
isMessage = fd.Message() != nil
case fd.Enum() != nil:
ft = fs.Type
if fd.HasPresence() && ft.Kind() == reflect.Ptr {
ft = ft.Elem()
}
case fd.Message() != nil:
ft = fs.Type
if fd.IsWeak() {
ft = nil
}
isMessage = true
}
if isMessage && ft != nil && ft.Kind() != reflect.Ptr {
ft = reflect.PtrTo(ft) // never occurs for officially generated message types
}
if ft != nil {
if mi.fieldTypes == nil {
mi.fieldTypes = make(map[protoreflect.FieldNumber]interface{})
}
mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface()
}
}
}
type extensionMap map[int32]ExtensionField type extensionMap map[int32]ExtensionField
func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) { func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
if m != nil { if m != nil {
for _, x := range *m { for _, x := range *m {
xd := x.Type().TypeDescriptor() xd := x.Type().TypeDescriptor()
@ -156,7 +247,7 @@ func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
} }
} }
} }
func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) { func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) {
if m == nil { if m == nil {
return false return false
} }
@ -175,10 +266,10 @@ func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) {
} }
return true return true
} }
func (m *extensionMap) Clear(xt pref.ExtensionType) { func (m *extensionMap) Clear(xt protoreflect.ExtensionType) {
delete(*m, int32(xt.TypeDescriptor().Number())) delete(*m, int32(xt.TypeDescriptor().Number()))
} }
func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value { func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value {
xd := xt.TypeDescriptor() xd := xt.TypeDescriptor()
if m != nil { if m != nil {
if x, ok := (*m)[int32(xd.Number())]; ok { if x, ok := (*m)[int32(xd.Number())]; ok {
@ -187,7 +278,7 @@ func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
} }
return xt.Zero() return xt.Zero()
} }
func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) { func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) {
xd := xt.TypeDescriptor() xd := xt.TypeDescriptor()
isValid := true isValid := true
switch { switch {
@ -211,9 +302,9 @@ func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
x.Set(xt, v) x.Set(xt, v)
(*m)[int32(xd.Number())] = x (*m)[int32(xd.Number())] = x
} }
func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value { func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value {
xd := xt.TypeDescriptor() xd := xt.TypeDescriptor()
if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() { if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() {
panic("invalid Mutable on field with non-composite type") panic("invalid Mutable on field with non-composite type")
} }
if x, ok := (*m)[int32(xd.Number())]; ok { if x, ok := (*m)[int32(xd.Number())]; ok {
@ -229,7 +320,6 @@ func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
// in an allocation-free way without needing to have a shadow Go type generated // in an allocation-free way without needing to have a shadow Go type generated
// for every message type. This technique only works using unsafe. // for every message type. This technique only works using unsafe.
// //
//
// Example generated code: // Example generated code:
// //
// type M struct { // type M struct {
@ -260,11 +350,10 @@ func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
// It has access to the message info as its first field, and a pointer to the // It has access to the message info as its first field, and a pointer to the
// MessageState is identical to a pointer to the concrete message value. // MessageState is identical to a pointer to the concrete message value.
// //
//
// Requirements: // Requirements:
// The type M must implement protoreflect.ProtoMessage. // - The type M must implement protoreflect.ProtoMessage.
// The address of m must not be nil. // - The address of m must not be nil.
// The address of m and the address of m.state must be equal, // - The address of m and the address of m.state must be equal,
// even though they are different Go types. // even though they are different Go types.
type MessageState struct { type MessageState struct {
pragma.NoUnkeyedLiterals pragma.NoUnkeyedLiterals
@ -277,7 +366,7 @@ type MessageState struct {
type messageState MessageState type messageState MessageState
var ( var (
_ pref.Message = (*messageState)(nil) _ protoreflect.Message = (*messageState)(nil)
_ unwrapper = (*messageState)(nil) _ unwrapper = (*messageState)(nil)
) )
@ -296,17 +385,16 @@ type (
) )
var ( var (
_ pref.Message = (*messageReflectWrapper)(nil) _ protoreflect.Message = (*messageReflectWrapper)(nil)
_ unwrapper = (*messageReflectWrapper)(nil) _ unwrapper = (*messageReflectWrapper)(nil)
_ pref.ProtoMessage = (*messageIfaceWrapper)(nil) _ protoreflect.ProtoMessage = (*messageIfaceWrapper)(nil)
_ unwrapper = (*messageIfaceWrapper)(nil) _ unwrapper = (*messageIfaceWrapper)(nil)
) )
// MessageOf returns a reflective view over a message. The input must be a // MessageOf returns a reflective view over a message. The input must be a
// pointer to a named Go struct. If the provided type has a ProtoReflect method, // pointer to a named Go struct. If the provided type has a ProtoReflect method,
// it must be implemented by calling this method. // it must be implemented by calling this method.
func (mi *MessageInfo) MessageOf(m interface{}) pref.Message { func (mi *MessageInfo) MessageOf(m interface{}) protoreflect.Message {
// TODO: Switch the input to be an opaque Pointer.
if reflect.TypeOf(m) != mi.GoReflectType { if reflect.TypeOf(m) != mi.GoReflectType {
panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType)) panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
} }
@ -320,7 +408,18 @@ func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
func (m *messageReflectWrapper) pointer() pointer { return m.p } func (m *messageReflectWrapper) pointer() pointer { return m.p }
func (m *messageReflectWrapper) messageInfo() *MessageInfo { return m.mi } func (m *messageReflectWrapper) messageInfo() *MessageInfo { return m.mi }
func (m *messageIfaceWrapper) ProtoReflect() pref.Message { // Reset implements the v1 proto.Message.Reset method.
func (m *messageIfaceWrapper) Reset() {
if mr, ok := m.protoUnwrap().(interface{ Reset() }); ok {
mr.Reset()
return
}
rv := reflect.ValueOf(m.protoUnwrap())
if rv.Kind() == reflect.Ptr && !rv.IsNil() {
rv.Elem().Set(reflect.Zero(rv.Type().Elem()))
}
}
func (m *messageIfaceWrapper) ProtoReflect() protoreflect.Message {
return (*messageReflectWrapper)(m) return (*messageReflectWrapper)(m)
} }
func (m *messageIfaceWrapper) protoUnwrap() interface{} { func (m *messageIfaceWrapper) protoUnwrap() interface{} {
@ -329,7 +428,7 @@ func (m *messageIfaceWrapper) protoUnwrap() interface{} {
// checkField verifies that the provided field descriptor is valid. // checkField verifies that the provided field descriptor is valid.
// Exactly one of the returned values is populated. // Exactly one of the returned values is populated.
func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) { func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) {
var fi *fieldInfo var fi *fieldInfo
if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) { if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
fi = mi.denseFields[n] fi = mi.denseFields[n]
@ -354,7 +453,7 @@ func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.Ext
if !mi.Desc.ExtensionRanges().Has(fd.Number()) { if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName())) panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName()))
} }
xtd, ok := fd.(pref.ExtensionTypeDescriptor) xtd, ok := fd.(protoreflect.ExtensionTypeDescriptor)
if !ok { if !ok {
panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName())) panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
} }

View File

@ -11,24 +11,57 @@ import (
"sync" "sync"
"google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/flags"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
type fieldInfo struct { type fieldInfo struct {
fieldDesc pref.FieldDescriptor fieldDesc protoreflect.FieldDescriptor
// These fields are used for protobuf reflection support. // These fields are used for protobuf reflection support.
has func(pointer) bool has func(pointer) bool
clear func(pointer) clear func(pointer)
get func(pointer) pref.Value get func(pointer) protoreflect.Value
set func(pointer, pref.Value) set func(pointer, protoreflect.Value)
mutable func(pointer) pref.Value mutable func(pointer) protoreflect.Value
newMessage func() pref.Message newMessage func() protoreflect.Message
newField func() pref.Value newField func() protoreflect.Value
} }
func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo { func fieldInfoForMissing(fd protoreflect.FieldDescriptor) fieldInfo {
// This never occurs for generated message types.
// It implies that a hand-crafted type has missing Go fields
// for specific protobuf message fields.
return fieldInfo{
fieldDesc: fd,
has: func(p pointer) bool {
return false
},
clear: func(p pointer) {
panic("missing Go struct field for " + string(fd.FullName()))
},
get: func(p pointer) protoreflect.Value {
return fd.Default()
},
set: func(p pointer, v protoreflect.Value) {
panic("missing Go struct field for " + string(fd.FullName()))
},
mutable: func(p pointer) protoreflect.Value {
panic("missing Go struct field for " + string(fd.FullName()))
},
newMessage: func() protoreflect.Message {
panic("missing Go struct field for " + string(fd.FullName()))
},
newField: func() protoreflect.Value {
if v := fd.Default(); v.IsValid() {
return v
}
panic("missing Go struct field for " + string(fd.FullName()))
},
}
}
func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
ft := fs.Type ft := fs.Type
if ft.Kind() != reflect.Interface { if ft.Kind() != reflect.Interface {
panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft)) panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft))
@ -69,7 +102,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export
} }
rv.Set(reflect.Zero(rv.Type())) rv.Set(reflect.Zero(rv.Type()))
}, },
get: func(p pointer) pref.Value { get: func(p pointer) protoreflect.Value {
if p.IsNil() { if p.IsNil() {
return conv.Zero() return conv.Zero()
} }
@ -80,7 +113,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export
rv = rv.Elem().Elem().Field(0) rv = rv.Elem().Elem().Field(0)
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
set: func(p pointer, v pref.Value) { set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
rv.Set(reflect.New(ot)) rv.Set(reflect.New(ot))
@ -88,7 +121,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export
rv = rv.Elem().Elem().Field(0) rv = rv.Elem().Elem().Field(0)
rv.Set(conv.GoValueOf(v)) rv.Set(conv.GoValueOf(v))
}, },
mutable: func(p pointer) pref.Value { mutable: func(p pointer) protoreflect.Value {
if !isMessage { if !isMessage {
panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName())) panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName()))
} }
@ -97,21 +130,21 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export
rv.Set(reflect.New(ot)) rv.Set(reflect.New(ot))
} }
rv = rv.Elem().Elem().Field(0) rv = rv.Elem().Elem().Field(0)
if rv.IsNil() { if rv.Kind() == reflect.Ptr && rv.IsNil() {
rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message()))) rv.Set(conv.GoValueOf(protoreflect.ValueOfMessage(conv.New().Message())))
} }
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
newMessage: func() pref.Message { newMessage: func() protoreflect.Message {
return conv.New().Message() return conv.New().Message()
}, },
newField: func() pref.Value { newField: func() protoreflect.Value {
return conv.New() return conv.New()
}, },
} }
} }
func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
ft := fs.Type ft := fs.Type
if ft.Kind() != reflect.Map { if ft.Kind() != reflect.Map {
panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft)) panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft))
@ -133,7 +166,7 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type())) rv.Set(reflect.Zero(rv.Type()))
}, },
get: func(p pointer) pref.Value { get: func(p pointer) protoreflect.Value {
if p.IsNil() { if p.IsNil() {
return conv.Zero() return conv.Zero()
} }
@ -143,7 +176,7 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter
} }
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
set: func(p pointer, v pref.Value) { set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
pv := conv.GoValueOf(v) pv := conv.GoValueOf(v)
if pv.IsNil() { if pv.IsNil() {
@ -151,20 +184,20 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter
} }
rv.Set(pv) rv.Set(pv)
}, },
mutable: func(p pointer) pref.Value { mutable: func(p pointer) protoreflect.Value {
v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if v.IsNil() { if v.IsNil() {
v.Set(reflect.MakeMap(fs.Type)) v.Set(reflect.MakeMap(fs.Type))
} }
return conv.PBValueOf(v) return conv.PBValueOf(v)
}, },
newField: func() pref.Value { newField: func() protoreflect.Value {
return conv.New() return conv.New()
}, },
} }
} }
func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
ft := fs.Type ft := fs.Type
if ft.Kind() != reflect.Slice { if ft.Kind() != reflect.Slice {
panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft)) panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft))
@ -186,7 +219,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type())) rv.Set(reflect.Zero(rv.Type()))
}, },
get: func(p pointer) pref.Value { get: func(p pointer) protoreflect.Value {
if p.IsNil() { if p.IsNil() {
return conv.Zero() return conv.Zero()
} }
@ -196,7 +229,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte
} }
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
set: func(p pointer, v pref.Value) { set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
pv := conv.GoValueOf(v) pv := conv.GoValueOf(v)
if pv.IsNil() { if pv.IsNil() {
@ -204,11 +237,11 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte
} }
rv.Set(pv.Elem()) rv.Set(pv.Elem())
}, },
mutable: func(p pointer) pref.Value { mutable: func(p pointer) protoreflect.Value {
v := p.Apply(fieldOffset).AsValueOf(fs.Type) v := p.Apply(fieldOffset).AsValueOf(fs.Type)
return conv.PBValueOf(v) return conv.PBValueOf(v)
}, },
newField: func() pref.Value { newField: func() protoreflect.Value {
return conv.New() return conv.New()
}, },
} }
@ -219,13 +252,16 @@ var (
emptyBytes = reflect.ValueOf([]byte{}) emptyBytes = reflect.ValueOf([]byte{})
) )
func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
ft := fs.Type ft := fs.Type
nullable := fd.HasPresence() nullable := fd.HasPresence()
isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
if nullable { if nullable {
if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice { if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
panic(fmt.Sprintf("field %v has invalid type: got %v, want pointer", fd.FullName(), ft)) // This never occurs for generated message types.
// Despite the protobuf type system specifying presence,
// the Go field type cannot represent it.
nullable = false
} }
if ft.Kind() == reflect.Ptr { if ft.Kind() == reflect.Ptr {
ft = ft.Elem() ft = ft.Elem()
@ -264,7 +300,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type())) rv.Set(reflect.Zero(rv.Type()))
}, },
get: func(p pointer) pref.Value { get: func(p pointer) protoreflect.Value {
if p.IsNil() { if p.IsNil() {
return conv.Zero() return conv.Zero()
} }
@ -279,7 +315,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor
} }
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
set: func(p pointer, v pref.Value) { set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if nullable && rv.Kind() == reflect.Ptr { if nullable && rv.Kind() == reflect.Ptr {
if rv.IsNil() { if rv.IsNil() {
@ -296,23 +332,23 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor
} }
} }
}, },
newField: func() pref.Value { newField: func() protoreflect.Value {
return conv.New() return conv.New()
}, },
} }
} }
func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo { func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo {
if !flags.ProtoLegacy { if !flags.ProtoLegacy {
panic("no support for proto1 weak fields") panic("no support for proto1 weak fields")
} }
var once sync.Once var once sync.Once
var messageType pref.MessageType var messageType protoreflect.MessageType
lazyInit := func() { lazyInit := func() {
once.Do(func() { once.Do(func() {
messageName := fd.Message().FullName() messageName := fd.Message().FullName()
messageType, _ = preg.GlobalTypes.FindMessageByName(messageName) messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
if messageType == nil { if messageType == nil {
panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName())) panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName()))
} }
@ -332,18 +368,18 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn
clear: func(p pointer) { clear: func(p pointer) {
p.Apply(weakOffset).WeakFields().clear(num) p.Apply(weakOffset).WeakFields().clear(num)
}, },
get: func(p pointer) pref.Value { get: func(p pointer) protoreflect.Value {
lazyInit() lazyInit()
if p.IsNil() { if p.IsNil() {
return pref.ValueOfMessage(messageType.Zero()) return protoreflect.ValueOfMessage(messageType.Zero())
} }
m, ok := p.Apply(weakOffset).WeakFields().get(num) m, ok := p.Apply(weakOffset).WeakFields().get(num)
if !ok { if !ok {
return pref.ValueOfMessage(messageType.Zero()) return protoreflect.ValueOfMessage(messageType.Zero())
} }
return pref.ValueOfMessage(m.ProtoReflect()) return protoreflect.ValueOfMessage(m.ProtoReflect())
}, },
set: func(p pointer, v pref.Value) { set: func(p pointer, v protoreflect.Value) {
lazyInit() lazyInit()
m := v.Message() m := v.Message()
if m.Descriptor() != messageType.Descriptor() { if m.Descriptor() != messageType.Descriptor() {
@ -354,7 +390,7 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn
} }
p.Apply(weakOffset).WeakFields().set(num, m.Interface()) p.Apply(weakOffset).WeakFields().set(num, m.Interface())
}, },
mutable: func(p pointer) pref.Value { mutable: func(p pointer) protoreflect.Value {
lazyInit() lazyInit()
fs := p.Apply(weakOffset).WeakFields() fs := p.Apply(weakOffset).WeakFields()
m, ok := fs.get(num) m, ok := fs.get(num)
@ -362,20 +398,20 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn
m = messageType.New().Interface() m = messageType.New().Interface()
fs.set(num, m) fs.set(num, m)
} }
return pref.ValueOfMessage(m.ProtoReflect()) return protoreflect.ValueOfMessage(m.ProtoReflect())
}, },
newMessage: func() pref.Message { newMessage: func() protoreflect.Message {
lazyInit() lazyInit()
return messageType.New() return messageType.New()
}, },
newField: func() pref.Value { newField: func() protoreflect.Value {
lazyInit() lazyInit()
return pref.ValueOfMessage(messageType.New()) return protoreflect.ValueOfMessage(messageType.New())
}, },
} }
} }
func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
ft := fs.Type ft := fs.Type
conv := NewConverter(ft, fd) conv := NewConverter(ft, fd)
@ -388,53 +424,56 @@ func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x expo
return false return false
} }
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if fs.Type.Kind() != reflect.Ptr {
return !isZero(rv)
}
return !rv.IsNil() return !rv.IsNil()
}, },
clear: func(p pointer) { clear: func(p pointer) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(reflect.Zero(rv.Type())) rv.Set(reflect.Zero(rv.Type()))
}, },
get: func(p pointer) pref.Value { get: func(p pointer) protoreflect.Value {
if p.IsNil() { if p.IsNil() {
return conv.Zero() return conv.Zero()
} }
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
set: func(p pointer, v pref.Value) { set: func(p pointer, v protoreflect.Value) {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
rv.Set(conv.GoValueOf(v)) rv.Set(conv.GoValueOf(v))
if rv.IsNil() { if fs.Type.Kind() == reflect.Ptr && rv.IsNil() {
panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName())) panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName()))
} }
}, },
mutable: func(p pointer) pref.Value { mutable: func(p pointer) protoreflect.Value {
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
if rv.IsNil() { if fs.Type.Kind() == reflect.Ptr && rv.IsNil() {
rv.Set(conv.GoValueOf(conv.New())) rv.Set(conv.GoValueOf(conv.New()))
} }
return conv.PBValueOf(rv) return conv.PBValueOf(rv)
}, },
newMessage: func() pref.Message { newMessage: func() protoreflect.Message {
return conv.New().Message() return conv.New().Message()
}, },
newField: func() pref.Value { newField: func() protoreflect.Value {
return conv.New() return conv.New()
}, },
} }
} }
type oneofInfo struct { type oneofInfo struct {
oneofDesc pref.OneofDescriptor oneofDesc protoreflect.OneofDescriptor
which func(pointer) pref.FieldNumber which func(pointer) protoreflect.FieldNumber
} }
func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInfo { func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
oi := &oneofInfo{oneofDesc: od} oi := &oneofInfo{oneofDesc: od}
if od.IsSynthetic() { if od.IsSynthetic() {
fs := si.fieldsByNumber[od.Fields().Get(0).Number()] fs := si.fieldsByNumber[od.Fields().Get(0).Number()]
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs, x)
oi.which = func(p pointer) pref.FieldNumber { oi.which = func(p pointer) protoreflect.FieldNumber {
if p.IsNil() { if p.IsNil() {
return 0 return 0
} }
@ -447,7 +486,7 @@ func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInf
} else { } else {
fs := si.oneofsByName[od.Name()] fs := si.oneofsByName[od.Name()]
fieldOffset := offsetOf(fs, x) fieldOffset := offsetOf(fs, x)
oi.which = func(p pointer) pref.FieldNumber { oi.which = func(p pointer) protoreflect.FieldNumber {
if p.IsNil() { if p.IsNil() {
return 0 return 0
} }
@ -464,3 +503,41 @@ func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInf
} }
return oi return oi
} }
// isZero is identical to reflect.Value.IsZero.
// TODO: Remove this when Go1.13 is the minimally supported Go version.
func isZero(v reflect.Value) bool {
switch v.Kind() {
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return math.Float64bits(v.Float()) == 0
case reflect.Complex64, reflect.Complex128:
c := v.Complex()
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
case reflect.Array:
for i := 0; i < v.Len(); i++ {
if !isZero(v.Index(i)) {
return false
}
}
return true
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
return v.IsNil()
case reflect.String:
return v.Len() == 0
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
if !isZero(v.Field(i)) {
return false
}
}
return true
default:
panic(&reflect.ValueError{"reflect.Value.IsZero", v.Kind()})
}
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build purego || appengine
// +build purego appengine // +build purego appengine
package impl package impl
@ -121,6 +122,7 @@ func (p pointer) String() *string { return p.v.Interface().(*string) }
func (p pointer) StringPtr() **string { return p.v.Interface().(**string) } func (p pointer) StringPtr() **string { return p.v.Interface().(**string) }
func (p pointer) StringSlice() *[]string { return p.v.Interface().(*[]string) } func (p pointer) StringSlice() *[]string { return p.v.Interface().(*[]string) }
func (p pointer) Bytes() *[]byte { return p.v.Interface().(*[]byte) } func (p pointer) Bytes() *[]byte { return p.v.Interface().(*[]byte) }
func (p pointer) BytesPtr() **[]byte { return p.v.Interface().(**[]byte) }
func (p pointer) BytesSlice() *[][]byte { return p.v.Interface().(*[][]byte) } func (p pointer) BytesSlice() *[][]byte { return p.v.Interface().(*[][]byte) }
func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.v.Interface().(*WeakFields)) } func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.v.Interface().(*WeakFields)) }
func (p pointer) Extensions() *map[int32]ExtensionField { func (p pointer) Extensions() *map[int32]ExtensionField {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !purego && !appengine
// +build !purego,!appengine // +build !purego,!appengine
package impl package impl
@ -109,6 +110,7 @@ func (p pointer) String() *string { return (*string)(p.p)
func (p pointer) StringPtr() **string { return (**string)(p.p) } func (p pointer) StringPtr() **string { return (**string)(p.p) }
func (p pointer) StringSlice() *[]string { return (*[]string)(p.p) } func (p pointer) StringSlice() *[]string { return (*[]string)(p.p) }
func (p pointer) Bytes() *[]byte { return (*[]byte)(p.p) } func (p pointer) Bytes() *[]byte { return (*[]byte)(p.p) }
func (p pointer) BytesPtr() **[]byte { return (**[]byte)(p.p) }
func (p pointer) BytesSlice() *[][]byte { return (*[][]byte)(p.p) } func (p pointer) BytesSlice() *[][]byte { return (*[][]byte)(p.p) }
func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.p) } func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.p) }
func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) } func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) }

View File

@ -16,9 +16,9 @@ import (
"google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/internal/strs"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
preg "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
piface "google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
) )
// ValidationStatus is the result of validating the wire-format encoding of a message. // ValidationStatus is the result of validating the wire-format encoding of a message.
@ -56,20 +56,20 @@ func (v ValidationStatus) String() string {
// of the message type. // of the message type.
// //
// This function is exposed for testing. // This function is exposed for testing.
func Validate(mt pref.MessageType, in piface.UnmarshalInput) (out piface.UnmarshalOutput, _ ValidationStatus) { func Validate(mt protoreflect.MessageType, in protoiface.UnmarshalInput) (out protoiface.UnmarshalOutput, _ ValidationStatus) {
mi, ok := mt.(*MessageInfo) mi, ok := mt.(*MessageInfo)
if !ok { if !ok {
return out, ValidationUnknown return out, ValidationUnknown
} }
if in.Resolver == nil { if in.Resolver == nil {
in.Resolver = preg.GlobalTypes in.Resolver = protoregistry.GlobalTypes
} }
o, st := mi.validate(in.Buf, 0, unmarshalOptions{ o, st := mi.validate(in.Buf, 0, unmarshalOptions{
flags: in.Flags, flags: in.Flags,
resolver: in.Resolver, resolver: in.Resolver,
}) })
if o.initialized { if o.initialized {
out.Flags |= piface.UnmarshalInitialized out.Flags |= protoiface.UnmarshalInitialized
} }
return out, st return out, st
} }
@ -106,22 +106,22 @@ const (
validationTypeMessageSetItem validationTypeMessageSetItem
) )
func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescriptor, ft reflect.Type) validationInfo { func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd protoreflect.FieldDescriptor, ft reflect.Type) validationInfo {
var vi validationInfo var vi validationInfo
switch { switch {
case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
switch fd.Kind() { switch fd.Kind() {
case pref.MessageKind: case protoreflect.MessageKind:
vi.typ = validationTypeMessage vi.typ = validationTypeMessage
if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok { if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
vi.mi = getMessageInfo(ot.Field(0).Type) vi.mi = getMessageInfo(ot.Field(0).Type)
} }
case pref.GroupKind: case protoreflect.GroupKind:
vi.typ = validationTypeGroup vi.typ = validationTypeGroup
if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok { if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
vi.mi = getMessageInfo(ot.Field(0).Type) vi.mi = getMessageInfo(ot.Field(0).Type)
} }
case pref.StringKind: case protoreflect.StringKind:
if strs.EnforceUTF8(fd) { if strs.EnforceUTF8(fd) {
vi.typ = validationTypeUTF8String vi.typ = validationTypeUTF8String
} }
@ -129,7 +129,7 @@ func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescrip
default: default:
vi = newValidationInfo(fd, ft) vi = newValidationInfo(fd, ft)
} }
if fd.Cardinality() == pref.Required { if fd.Cardinality() == protoreflect.Required {
// Avoid overflow. The required field check is done with a 64-bit mask, with // Avoid overflow. The required field check is done with a 64-bit mask, with
// any message containing more than 64 required fields always reported as // any message containing more than 64 required fields always reported as
// potentially uninitialized, so it is not important to get a precise count // potentially uninitialized, so it is not important to get a precise count
@ -142,22 +142,22 @@ func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescrip
return vi return vi
} }
func newValidationInfo(fd pref.FieldDescriptor, ft reflect.Type) validationInfo { func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validationInfo {
var vi validationInfo var vi validationInfo
switch { switch {
case fd.IsList(): case fd.IsList():
switch fd.Kind() { switch fd.Kind() {
case pref.MessageKind: case protoreflect.MessageKind:
vi.typ = validationTypeMessage vi.typ = validationTypeMessage
if ft.Kind() == reflect.Slice { if ft.Kind() == reflect.Slice {
vi.mi = getMessageInfo(ft.Elem()) vi.mi = getMessageInfo(ft.Elem())
} }
case pref.GroupKind: case protoreflect.GroupKind:
vi.typ = validationTypeGroup vi.typ = validationTypeGroup
if ft.Kind() == reflect.Slice { if ft.Kind() == reflect.Slice {
vi.mi = getMessageInfo(ft.Elem()) vi.mi = getMessageInfo(ft.Elem())
} }
case pref.StringKind: case protoreflect.StringKind:
vi.typ = validationTypeBytes vi.typ = validationTypeBytes
if strs.EnforceUTF8(fd) { if strs.EnforceUTF8(fd) {
vi.typ = validationTypeUTF8String vi.typ = validationTypeUTF8String
@ -175,33 +175,33 @@ func newValidationInfo(fd pref.FieldDescriptor, ft reflect.Type) validationInfo
case fd.IsMap(): case fd.IsMap():
vi.typ = validationTypeMap vi.typ = validationTypeMap
switch fd.MapKey().Kind() { switch fd.MapKey().Kind() {
case pref.StringKind: case protoreflect.StringKind:
if strs.EnforceUTF8(fd) { if strs.EnforceUTF8(fd) {
vi.keyType = validationTypeUTF8String vi.keyType = validationTypeUTF8String
} }
} }
switch fd.MapValue().Kind() { switch fd.MapValue().Kind() {
case pref.MessageKind: case protoreflect.MessageKind:
vi.valType = validationTypeMessage vi.valType = validationTypeMessage
if ft.Kind() == reflect.Map { if ft.Kind() == reflect.Map {
vi.mi = getMessageInfo(ft.Elem()) vi.mi = getMessageInfo(ft.Elem())
} }
case pref.StringKind: case protoreflect.StringKind:
if strs.EnforceUTF8(fd) { if strs.EnforceUTF8(fd) {
vi.valType = validationTypeUTF8String vi.valType = validationTypeUTF8String
} }
} }
default: default:
switch fd.Kind() { switch fd.Kind() {
case pref.MessageKind: case protoreflect.MessageKind:
vi.typ = validationTypeMessage vi.typ = validationTypeMessage
if !fd.IsWeak() { if !fd.IsWeak() {
vi.mi = getMessageInfo(ft) vi.mi = getMessageInfo(ft)
} }
case pref.GroupKind: case protoreflect.GroupKind:
vi.typ = validationTypeGroup vi.typ = validationTypeGroup
vi.mi = getMessageInfo(ft) vi.mi = getMessageInfo(ft)
case pref.StringKind: case protoreflect.StringKind:
vi.typ = validationTypeBytes vi.typ = validationTypeBytes
if strs.EnforceUTF8(fd) { if strs.EnforceUTF8(fd) {
vi.typ = validationTypeUTF8String vi.typ = validationTypeUTF8String
@ -314,11 +314,11 @@ State:
break break
} }
messageName := fd.Message().FullName() messageName := fd.Message().FullName()
messageType, err := preg.GlobalTypes.FindMessageByName(messageName) messageType, err := protoregistry.GlobalTypes.FindMessageByName(messageName)
switch err { switch err {
case nil: case nil:
vi.mi, _ = messageType.(*MessageInfo) vi.mi, _ = messageType.(*MessageInfo)
case preg.NotFound: case protoregistry.NotFound:
vi.typ = validationTypeBytes vi.typ = validationTypeBytes
default: default:
return out, ValidationUnknown return out, ValidationUnknown
@ -335,7 +335,7 @@ State:
// unmarshaling to begin failing. Supporting this requires some way to // unmarshaling to begin failing. Supporting this requires some way to
// determine if the resolver is frozen. // determine if the resolver is frozen.
xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), num) xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), num)
if err != nil && err != preg.NotFound { if err != nil && err != protoregistry.NotFound {
return out, ValidationUnknown return out, ValidationUnknown
} }
if err == nil { if err == nil {
@ -513,7 +513,7 @@ State:
} }
xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), typeid) xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), typeid)
switch { switch {
case err == preg.NotFound: case err == protoregistry.NotFound:
b = b[n:] b = b[n:]
case err != nil: case err != nil:
return out, ValidationUnknown return out, ValidationUnknown

View File

@ -7,7 +7,7 @@ package impl
import ( import (
"fmt" "fmt"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
@ -17,32 +17,32 @@ import (
// defined directly on it. // defined directly on it.
type weakFields WeakFields type weakFields WeakFields
func (w weakFields) get(num pref.FieldNumber) (pref.ProtoMessage, bool) { func (w weakFields) get(num protoreflect.FieldNumber) (protoreflect.ProtoMessage, bool) {
m, ok := w[int32(num)] m, ok := w[int32(num)]
return m, ok return m, ok
} }
func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) { func (w *weakFields) set(num protoreflect.FieldNumber, m protoreflect.ProtoMessage) {
if *w == nil { if *w == nil {
*w = make(weakFields) *w = make(weakFields)
} }
(*w)[int32(num)] = m (*w)[int32(num)] = m
} }
func (w *weakFields) clear(num pref.FieldNumber) { func (w *weakFields) clear(num protoreflect.FieldNumber) {
delete(*w, int32(num)) delete(*w, int32(num))
} }
func (Export) HasWeak(w WeakFields, num pref.FieldNumber) bool { func (Export) HasWeak(w WeakFields, num protoreflect.FieldNumber) bool {
_, ok := w[int32(num)] _, ok := w[int32(num)]
return ok return ok
} }
func (Export) ClearWeak(w *WeakFields, num pref.FieldNumber) { func (Export) ClearWeak(w *WeakFields, num protoreflect.FieldNumber) {
delete(*w, int32(num)) delete(*w, int32(num))
} }
func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pref.ProtoMessage { func (Export) GetWeak(w WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName) protoreflect.ProtoMessage {
if m, ok := w[int32(num)]; ok { if m, ok := w[int32(num)]; ok {
return m return m
} }
@ -53,7 +53,7 @@ func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pr
return mt.Zero().Interface() return mt.Zero().Interface()
} }
func (Export) SetWeak(w *WeakFields, num pref.FieldNumber, name pref.FullName, m pref.ProtoMessage) { func (Export) SetWeak(w *WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName, m protoreflect.ProtoMessage) {
if m != nil { if m != nil {
mt, _ := protoregistry.GlobalTypes.FindMessageByName(name) mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
if mt == nil { if mt == nil {

View File

@ -1,43 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package mapsort provides sorted access to maps.
package mapsort
import (
"sort"
"google.golang.org/protobuf/reflect/protoreflect"
)
// Range iterates over every map entry in sorted key order,
// calling f for each key and value encountered.
func Range(mapv protoreflect.Map, keyKind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
var keys []protoreflect.MapKey
mapv.Range(func(key protoreflect.MapKey, _ protoreflect.Value) bool {
keys = append(keys, key)
return true
})
sort.Slice(keys, func(i, j int) bool {
switch keyKind {
case protoreflect.BoolKind:
return !keys[i].Bool() && keys[j].Bool()
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind,
protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
return keys[i].Int() < keys[j].Int()
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind,
protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
return keys[i].Uint() < keys[j].Uint()
case protoreflect.StringKind:
return keys[i].String() < keys[j].String()
default:
panic("invalid kind: " + keyKind.String())
}
})
for _, key := range keys {
if !f(key, mapv.Get(key)) {
break
}
}
}

View File

@ -0,0 +1,89 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package order
import (
"google.golang.org/protobuf/reflect/protoreflect"
)
// FieldOrder specifies the ordering to visit message fields.
// It is a function that reports whether x is ordered before y.
type FieldOrder func(x, y protoreflect.FieldDescriptor) bool
var (
// AnyFieldOrder specifies no specific field ordering.
AnyFieldOrder FieldOrder = nil
// LegacyFieldOrder sorts fields in the same ordering as emitted by
// wire serialization in the github.com/golang/protobuf implementation.
LegacyFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool {
ox, oy := x.ContainingOneof(), y.ContainingOneof()
inOneof := func(od protoreflect.OneofDescriptor) bool {
return od != nil && !od.IsSynthetic()
}
// Extension fields sort before non-extension fields.
if x.IsExtension() != y.IsExtension() {
return x.IsExtension() && !y.IsExtension()
}
// Fields not within a oneof sort before those within a oneof.
if inOneof(ox) != inOneof(oy) {
return !inOneof(ox) && inOneof(oy)
}
// Fields in disjoint oneof sets are sorted by declaration index.
if ox != nil && oy != nil && ox != oy {
return ox.Index() < oy.Index()
}
// Fields sorted by field number.
return x.Number() < y.Number()
}
// NumberFieldOrder sorts fields by their field number.
NumberFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool {
return x.Number() < y.Number()
}
// IndexNameFieldOrder sorts non-extension fields before extension fields.
// Non-extensions are sorted according to their declaration index.
// Extensions are sorted according to their full name.
IndexNameFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool {
// Non-extension fields sort before extension fields.
if x.IsExtension() != y.IsExtension() {
return !x.IsExtension() && y.IsExtension()
}
// Extensions sorted by fullname.
if x.IsExtension() && y.IsExtension() {
return x.FullName() < y.FullName()
}
// Non-extensions sorted by declaration index.
return x.Index() < y.Index()
}
)
// KeyOrder specifies the ordering to visit map entries.
// It is a function that reports whether x is ordered before y.
type KeyOrder func(x, y protoreflect.MapKey) bool
var (
// AnyKeyOrder specifies no specific key ordering.
AnyKeyOrder KeyOrder = nil
// GenericKeyOrder sorts false before true, numeric keys in ascending order,
// and strings in lexicographical ordering according to UTF-8 codepoints.
GenericKeyOrder KeyOrder = func(x, y protoreflect.MapKey) bool {
switch x.Interface().(type) {
case bool:
return !x.Bool() && y.Bool()
case int32, int64:
return x.Int() < y.Int()
case uint32, uint64:
return x.Uint() < y.Uint()
case string:
return x.String() < y.String()
default:
panic("invalid map key type")
}
}
)

View File

@ -0,0 +1,115 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package order provides ordered access to messages and maps.
package order
import (
"sort"
"sync"
"google.golang.org/protobuf/reflect/protoreflect"
)
type messageField struct {
fd protoreflect.FieldDescriptor
v protoreflect.Value
}
var messageFieldPool = sync.Pool{
New: func() interface{} { return new([]messageField) },
}
type (
// FieldRnger is an interface for visiting all fields in a message.
// The protoreflect.Message type implements this interface.
FieldRanger interface{ Range(VisitField) }
// VisitField is called every time a message field is visited.
VisitField = func(protoreflect.FieldDescriptor, protoreflect.Value) bool
)
// RangeFields iterates over the fields of fs according to the specified order.
func RangeFields(fs FieldRanger, less FieldOrder, fn VisitField) {
if less == nil {
fs.Range(fn)
return
}
// Obtain a pre-allocated scratch buffer.
p := messageFieldPool.Get().(*[]messageField)
fields := (*p)[:0]
defer func() {
if cap(fields) < 1024 {
*p = fields
messageFieldPool.Put(p)
}
}()
// Collect all fields in the message and sort them.
fs.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
fields = append(fields, messageField{fd, v})
return true
})
sort.Slice(fields, func(i, j int) bool {
return less(fields[i].fd, fields[j].fd)
})
// Visit the fields in the specified ordering.
for _, f := range fields {
if !fn(f.fd, f.v) {
return
}
}
}
type mapEntry struct {
k protoreflect.MapKey
v protoreflect.Value
}
var mapEntryPool = sync.Pool{
New: func() interface{} { return new([]mapEntry) },
}
type (
// EntryRanger is an interface for visiting all fields in a message.
// The protoreflect.Map type implements this interface.
EntryRanger interface{ Range(VisitEntry) }
// VisitEntry is called every time a map entry is visited.
VisitEntry = func(protoreflect.MapKey, protoreflect.Value) bool
)
// RangeEntries iterates over the entries of es according to the specified order.
func RangeEntries(es EntryRanger, less KeyOrder, fn VisitEntry) {
if less == nil {
es.Range(fn)
return
}
// Obtain a pre-allocated scratch buffer.
p := mapEntryPool.Get().(*[]mapEntry)
entries := (*p)[:0]
defer func() {
if cap(entries) < 1024 {
*p = entries
mapEntryPool.Put(p)
}
}()
// Collect all entries in the map and sort them.
es.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
entries = append(entries, mapEntry{k, v})
return true
})
sort.Slice(entries, func(i, j int) bool {
return less(entries[i].k, entries[j].k)
})
// Visit the entries in the specified ordering.
for _, e := range entries {
if !fn(e.k, e.v) {
return
}
}
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build purego || appengine
// +build purego appengine // +build purego appengine
package strs package strs

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !purego && !appengine
// +build !purego,!appengine // +build !purego,!appengine
package strs package strs
@ -9,7 +10,7 @@ package strs
import ( import (
"unsafe" "unsafe"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
type ( type (
@ -58,7 +59,7 @@ type Builder struct {
// AppendFullName is equivalent to protoreflect.FullName.Append, // AppendFullName is equivalent to protoreflect.FullName.Append,
// but optimized for large batches where each name has a shared lifetime. // but optimized for large batches where each name has a shared lifetime.
func (sb *Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.FullName { func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName {
n := len(prefix) + len(".") + len(name) n := len(prefix) + len(".") + len(name)
if len(prefix) == 0 { if len(prefix) == 0 {
n -= len(".") n -= len(".")
@ -67,7 +68,7 @@ func (sb *Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.Ful
sb.buf = append(sb.buf, prefix...) sb.buf = append(sb.buf, prefix...)
sb.buf = append(sb.buf, '.') sb.buf = append(sb.buf, '.')
sb.buf = append(sb.buf, name...) sb.buf = append(sb.buf, name...)
return pref.FullName(sb.last(n)) return protoreflect.FullName(sb.last(n))
} }
// MakeString is equivalent to string(b), but optimized for large batches // MakeString is equivalent to string(b), but optimized for large batches

View File

@ -12,16 +12,15 @@ import (
// These constants determine the current version of this module. // These constants determine the current version of this module.
// //
//
// For our release process, we enforce the following rules: // For our release process, we enforce the following rules:
// * Tagged releases use a tag that is identical to String. // - Tagged releases use a tag that is identical to String.
// * Tagged releases never reference a commit where the String // - Tagged releases never reference a commit where the String
// contains "devel". // contains "devel".
// * The set of all commits in this repository where String // - The set of all commits in this repository where String
// does not contain "devel" must have a unique String. // does not contain "devel" must have a unique String.
// //
//
// Steps for tagging a new release: // Steps for tagging a new release:
//
// 1. Create a new CL. // 1. Create a new CL.
// //
// 2. Update Minor, Patch, and/or PreRelease as necessary. // 2. Update Minor, Patch, and/or PreRelease as necessary.
@ -52,14 +51,15 @@ import (
// 10. Send out the CL for review and submit it. // 10. Send out the CL for review and submit it.
const ( const (
Major = 1 Major = 1
Minor = 25 Minor = 28
Patch = 0 Patch = 1
PreRelease = "" PreRelease = ""
) )
// String formats the version string for this module in semver format. // String formats the version string for this module in semver format.
// //
// Examples: // Examples:
//
// v1.20.1 // v1.20.1
// v1.21.0-rc.1 // v1.21.0-rc.1
func String() string { func String() string {

View File

@ -19,6 +19,7 @@ import (
// UnmarshalOptions configures the unmarshaler. // UnmarshalOptions configures the unmarshaler.
// //
// Example usage: // Example usage:
//
// err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m) // err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
type UnmarshalOptions struct { type UnmarshalOptions struct {
pragma.NoUnkeyedLiterals pragma.NoUnkeyedLiterals
@ -42,16 +43,25 @@ type UnmarshalOptions struct {
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
} }
// RecursionLimit limits how deeply messages may be nested.
// If zero, a default limit is applied.
RecursionLimit int
} }
// Unmarshal parses the wire-format message in b and places the result in m. // Unmarshal parses the wire-format message in b and places the result in m.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func Unmarshal(b []byte, m Message) error { func Unmarshal(b []byte, m Message) error {
_, err := UnmarshalOptions{}.unmarshal(b, m.ProtoReflect()) _, err := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(b, m.ProtoReflect())
return err return err
} }
// Unmarshal parses the wire-format message in b and places the result in m. // Unmarshal parses the wire-format message in b and places the result in m.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error { func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
if o.RecursionLimit == 0 {
o.RecursionLimit = protowire.DefaultRecursionLimit
}
_, err := o.unmarshal(b, m.ProtoReflect()) _, err := o.unmarshal(b, m.ProtoReflect())
return err return err
} }
@ -61,6 +71,9 @@ func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
// This method permits fine-grained control over the unmarshaler. // This method permits fine-grained control over the unmarshaler.
// Most users should use Unmarshal instead. // Most users should use Unmarshal instead.
func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
if o.RecursionLimit == 0 {
o.RecursionLimit = protowire.DefaultRecursionLimit
}
return o.unmarshal(in.Buf, in.Message) return o.unmarshal(in.Buf, in.Message)
} }
@ -84,12 +97,17 @@ func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out proto
Message: m, Message: m,
Buf: b, Buf: b,
Resolver: o.Resolver, Resolver: o.Resolver,
Depth: o.RecursionLimit,
} }
if o.DiscardUnknown { if o.DiscardUnknown {
in.Flags |= protoiface.UnmarshalDiscardUnknown in.Flags |= protoiface.UnmarshalDiscardUnknown
} }
out, err = methods.Unmarshal(in) out, err = methods.Unmarshal(in)
} else { } else {
o.RecursionLimit--
if o.RecursionLimit < 0 {
return out, errors.New("exceeded max recursion depth")
}
err = o.unmarshalMessageSlow(b, m) err = o.unmarshalMessageSlow(b, m)
} }
if err != nil { if err != nil {
@ -116,10 +134,10 @@ func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message)
// Parse the tag (field number and wire type). // Parse the tag (field number and wire type).
num, wtyp, tagLen := protowire.ConsumeTag(b) num, wtyp, tagLen := protowire.ConsumeTag(b)
if tagLen < 0 { if tagLen < 0 {
return protowire.ParseError(tagLen) return errDecode
} }
if num > protowire.MaxValidNumber { if num > protowire.MaxValidNumber {
return errors.New("invalid field number") return errDecode
} }
// Find the field descriptor for this field number. // Find the field descriptor for this field number.
@ -159,7 +177,7 @@ func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message)
} }
valLen = protowire.ConsumeFieldValue(num, wtyp, b[tagLen:]) valLen = protowire.ConsumeFieldValue(num, wtyp, b[tagLen:])
if valLen < 0 { if valLen < 0 {
return protowire.ParseError(valLen) return errDecode
} }
if !o.DiscardUnknown { if !o.DiscardUnknown {
m.SetUnknown(append(m.GetUnknown(), b[:tagLen+valLen]...)) m.SetUnknown(append(m.GetUnknown(), b[:tagLen+valLen]...))
@ -194,7 +212,7 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv proto
} }
b, n = protowire.ConsumeBytes(b) b, n = protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
var ( var (
keyField = fd.MapKey() keyField = fd.MapKey()
@ -213,10 +231,10 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv proto
for len(b) > 0 { for len(b) > 0 {
num, wtyp, n := protowire.ConsumeTag(b) num, wtyp, n := protowire.ConsumeTag(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
if num > protowire.MaxValidNumber { if num > protowire.MaxValidNumber {
return 0, errors.New("invalid field number") return 0, errDecode
} }
b = b[n:] b = b[n:]
err = errUnknown err = errUnknown
@ -246,7 +264,7 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv proto
if err == errUnknown { if err == errUnknown {
n = protowire.ConsumeFieldValue(num, wtyp, b) n = protowire.ConsumeFieldValue(num, wtyp, b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
} else if err != nil { } else if err != nil {
return 0, err return 0, err
@ -272,3 +290,5 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv proto
// to the unknown field set of a message. It is never returned from an exported // to the unknown field set of a message. It is never returned from an exported
// function. // function.
var errUnknown = errors.New("BUG: internal error (unknown)") var errUnknown = errors.New("BUG: internal error (unknown)")
var errDecode = errors.New("cannot parse invalid wire-format data")

View File

@ -27,7 +27,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfBool(protowire.DecodeBool(v)), n, nil return protoreflect.ValueOfBool(protowire.DecodeBool(v)), n, nil
case protoreflect.EnumKind: case protoreflect.EnumKind:
@ -36,7 +36,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)), n, nil return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)), n, nil
case protoreflect.Int32Kind: case protoreflect.Int32Kind:
@ -45,7 +45,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfInt32(int32(v)), n, nil return protoreflect.ValueOfInt32(int32(v)), n, nil
case protoreflect.Sint32Kind: case protoreflect.Sint32Kind:
@ -54,7 +54,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))), n, nil return protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))), n, nil
case protoreflect.Uint32Kind: case protoreflect.Uint32Kind:
@ -63,7 +63,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfUint32(uint32(v)), n, nil return protoreflect.ValueOfUint32(uint32(v)), n, nil
case protoreflect.Int64Kind: case protoreflect.Int64Kind:
@ -72,7 +72,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfInt64(int64(v)), n, nil return protoreflect.ValueOfInt64(int64(v)), n, nil
case protoreflect.Sint64Kind: case protoreflect.Sint64Kind:
@ -81,7 +81,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)), n, nil return protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)), n, nil
case protoreflect.Uint64Kind: case protoreflect.Uint64Kind:
@ -90,7 +90,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfUint64(v), n, nil return protoreflect.ValueOfUint64(v), n, nil
case protoreflect.Sfixed32Kind: case protoreflect.Sfixed32Kind:
@ -99,7 +99,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeFixed32(b) v, n := protowire.ConsumeFixed32(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfInt32(int32(v)), n, nil return protoreflect.ValueOfInt32(int32(v)), n, nil
case protoreflect.Fixed32Kind: case protoreflect.Fixed32Kind:
@ -108,7 +108,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeFixed32(b) v, n := protowire.ConsumeFixed32(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfUint32(uint32(v)), n, nil return protoreflect.ValueOfUint32(uint32(v)), n, nil
case protoreflect.FloatKind: case protoreflect.FloatKind:
@ -117,7 +117,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeFixed32(b) v, n := protowire.ConsumeFixed32(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))), n, nil return protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))), n, nil
case protoreflect.Sfixed64Kind: case protoreflect.Sfixed64Kind:
@ -126,7 +126,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeFixed64(b) v, n := protowire.ConsumeFixed64(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfInt64(int64(v)), n, nil return protoreflect.ValueOfInt64(int64(v)), n, nil
case protoreflect.Fixed64Kind: case protoreflect.Fixed64Kind:
@ -135,7 +135,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeFixed64(b) v, n := protowire.ConsumeFixed64(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfUint64(v), n, nil return protoreflect.ValueOfUint64(v), n, nil
case protoreflect.DoubleKind: case protoreflect.DoubleKind:
@ -144,7 +144,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeFixed64(b) v, n := protowire.ConsumeFixed64(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfFloat64(math.Float64frombits(v)), n, nil return protoreflect.ValueOfFloat64(math.Float64frombits(v)), n, nil
case protoreflect.StringKind: case protoreflect.StringKind:
@ -153,7 +153,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
if strs.EnforceUTF8(fd) && !utf8.Valid(v) { if strs.EnforceUTF8(fd) && !utf8.Valid(v) {
return protoreflect.Value{}, 0, errors.InvalidUTF8(string(fd.FullName())) return protoreflect.Value{}, 0, errors.InvalidUTF8(string(fd.FullName()))
@ -165,7 +165,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfBytes(append(emptyBuf[:], v...)), n, nil return protoreflect.ValueOfBytes(append(emptyBuf[:], v...)), n, nil
case protoreflect.MessageKind: case protoreflect.MessageKind:
@ -174,7 +174,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfBytes(v), n, nil return protoreflect.ValueOfBytes(v), n, nil
case protoreflect.GroupKind: case protoreflect.GroupKind:
@ -183,7 +183,7 @@ func (o UnmarshalOptions) unmarshalScalar(b []byte, wtyp protowire.Type, fd prot
} }
v, n := protowire.ConsumeGroup(fd.Number(), b) v, n := protowire.ConsumeGroup(fd.Number(), b)
if n < 0 { if n < 0 {
return val, 0, protowire.ParseError(n) return val, 0, errDecode
} }
return protoreflect.ValueOfBytes(v), n, nil return protoreflect.ValueOfBytes(v), n, nil
default: default:
@ -197,12 +197,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v))) list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v)))
@ -214,7 +214,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v))) list.Append(protoreflect.ValueOfBool(protowire.DecodeBool(v)))
return n, nil return n, nil
@ -222,12 +222,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v))) list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
@ -239,7 +239,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v))) list.Append(protoreflect.ValueOfEnum(protoreflect.EnumNumber(v)))
return n, nil return n, nil
@ -247,12 +247,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfInt32(int32(v))) list.Append(protoreflect.ValueOfInt32(int32(v)))
@ -264,7 +264,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfInt32(int32(v))) list.Append(protoreflect.ValueOfInt32(int32(v)))
return n, nil return n, nil
@ -272,12 +272,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32)))) list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))))
@ -289,7 +289,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32)))) list.Append(protoreflect.ValueOfInt32(int32(protowire.DecodeZigZag(v & math.MaxUint32))))
return n, nil return n, nil
@ -297,12 +297,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfUint32(uint32(v))) list.Append(protoreflect.ValueOfUint32(uint32(v)))
@ -314,7 +314,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfUint32(uint32(v))) list.Append(protoreflect.ValueOfUint32(uint32(v)))
return n, nil return n, nil
@ -322,12 +322,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfInt64(int64(v))) list.Append(protoreflect.ValueOfInt64(int64(v)))
@ -339,7 +339,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfInt64(int64(v))) list.Append(protoreflect.ValueOfInt64(int64(v)))
return n, nil return n, nil
@ -347,12 +347,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v))) list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)))
@ -364,7 +364,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v))) list.Append(protoreflect.ValueOfInt64(protowire.DecodeZigZag(v)))
return n, nil return n, nil
@ -372,12 +372,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeVarint(buf) v, n := protowire.ConsumeVarint(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfUint64(v)) list.Append(protoreflect.ValueOfUint64(v))
@ -389,7 +389,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeVarint(b) v, n := protowire.ConsumeVarint(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfUint64(v)) list.Append(protoreflect.ValueOfUint64(v))
return n, nil return n, nil
@ -397,12 +397,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeFixed32(buf) v, n := protowire.ConsumeFixed32(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfInt32(int32(v))) list.Append(protoreflect.ValueOfInt32(int32(v)))
@ -414,7 +414,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeFixed32(b) v, n := protowire.ConsumeFixed32(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfInt32(int32(v))) list.Append(protoreflect.ValueOfInt32(int32(v)))
return n, nil return n, nil
@ -422,12 +422,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeFixed32(buf) v, n := protowire.ConsumeFixed32(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfUint32(uint32(v))) list.Append(protoreflect.ValueOfUint32(uint32(v)))
@ -439,7 +439,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeFixed32(b) v, n := protowire.ConsumeFixed32(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfUint32(uint32(v))) list.Append(protoreflect.ValueOfUint32(uint32(v)))
return n, nil return n, nil
@ -447,12 +447,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeFixed32(buf) v, n := protowire.ConsumeFixed32(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v)))) list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
@ -464,7 +464,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeFixed32(b) v, n := protowire.ConsumeFixed32(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v)))) list.Append(protoreflect.ValueOfFloat32(math.Float32frombits(uint32(v))))
return n, nil return n, nil
@ -472,12 +472,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeFixed64(buf) v, n := protowire.ConsumeFixed64(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfInt64(int64(v))) list.Append(protoreflect.ValueOfInt64(int64(v)))
@ -489,7 +489,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeFixed64(b) v, n := protowire.ConsumeFixed64(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfInt64(int64(v))) list.Append(protoreflect.ValueOfInt64(int64(v)))
return n, nil return n, nil
@ -497,12 +497,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeFixed64(buf) v, n := protowire.ConsumeFixed64(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfUint64(v)) list.Append(protoreflect.ValueOfUint64(v))
@ -514,7 +514,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeFixed64(b) v, n := protowire.ConsumeFixed64(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfUint64(v)) list.Append(protoreflect.ValueOfUint64(v))
return n, nil return n, nil
@ -522,12 +522,12 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
if wtyp == protowire.BytesType { if wtyp == protowire.BytesType {
buf, n := protowire.ConsumeBytes(b) buf, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
for len(buf) > 0 { for len(buf) > 0 {
v, n := protowire.ConsumeFixed64(buf) v, n := protowire.ConsumeFixed64(buf)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
buf = buf[n:] buf = buf[n:]
list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v))) list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
@ -539,7 +539,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeFixed64(b) v, n := protowire.ConsumeFixed64(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v))) list.Append(protoreflect.ValueOfFloat64(math.Float64frombits(v)))
return n, nil return n, nil
@ -549,7 +549,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
if strs.EnforceUTF8(fd) && !utf8.Valid(v) { if strs.EnforceUTF8(fd) && !utf8.Valid(v) {
return 0, errors.InvalidUTF8(string(fd.FullName())) return 0, errors.InvalidUTF8(string(fd.FullName()))
@ -562,7 +562,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
list.Append(protoreflect.ValueOfBytes(append(emptyBuf[:], v...))) list.Append(protoreflect.ValueOfBytes(append(emptyBuf[:], v...)))
return n, nil return n, nil
@ -572,7 +572,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeBytes(b) v, n := protowire.ConsumeBytes(b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
m := list.NewElement() m := list.NewElement()
if err := o.unmarshalMessage(v, m.Message()); err != nil { if err := o.unmarshalMessage(v, m.Message()); err != nil {
@ -586,7 +586,7 @@ func (o UnmarshalOptions) unmarshalList(b []byte, wtyp protowire.Type, list prot
} }
v, n := protowire.ConsumeGroup(fd.Number(), b) v, n := protowire.ConsumeGroup(fd.Number(), b)
if n < 0 { if n < 0 {
return 0, protowire.ParseError(n) return 0, errDecode
} }
m := list.NewElement() m := list.NewElement()
if err := o.unmarshalMessage(v, m.Message()); err != nil { if err := o.unmarshalMessage(v, m.Message()); err != nil {

View File

@ -16,8 +16,7 @@
// //
// https://developers.google.com/protocol-buffers/docs/reference/go-generated // https://developers.google.com/protocol-buffers/docs/reference/go-generated
// //
// // # Binary serialization
// Binary serialization
// //
// This package contains functions to convert to and from the wire format, // This package contains functions to convert to and from the wire format,
// an efficient binary serialization of protocol buffers. // an efficient binary serialization of protocol buffers.
@ -30,8 +29,7 @@
// • Unmarshal converts a message from the wire format. // • Unmarshal converts a message from the wire format.
// The UnmarshalOptions type provides more control over wire unmarshaling. // The UnmarshalOptions type provides more control over wire unmarshaling.
// //
// // # Basic message operations
// Basic message operations
// //
// • Clone makes a deep copy of a message. // • Clone makes a deep copy of a message.
// //
@ -45,8 +43,7 @@
// //
// • CheckInitialized reports whether all required fields in a message are set. // • CheckInitialized reports whether all required fields in a message are set.
// //
// // # Optional scalar constructors
// Optional scalar constructors
// //
// The API for some generated messages represents optional scalar fields // The API for some generated messages represents optional scalar fields
// as pointers to a value. For example, an optional string field has the // as pointers to a value. For example, an optional string field has the
@ -61,16 +58,14 @@
// //
// Optional scalar fields are only supported in proto2. // Optional scalar fields are only supported in proto2.
// //
// // # Extension accessors
// Extension accessors
// //
// • HasExtension, GetExtension, SetExtension, and ClearExtension // • HasExtension, GetExtension, SetExtension, and ClearExtension
// access extension field values in a protocol buffer message. // access extension field values in a protocol buffer message.
// //
// Extension fields are only supported in proto2. // Extension fields are only supported in proto2.
// //
// // # Related packages
// Related packages
// //
// • Package "google.golang.org/protobuf/encoding/protojson" converts messages to // • Package "google.golang.org/protobuf/encoding/protojson" converts messages to
// and from JSON. // and from JSON.

View File

@ -5,12 +5,9 @@
package proto package proto
import ( import (
"sort"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/fieldsort" "google.golang.org/protobuf/internal/order"
"google.golang.org/protobuf/internal/mapsort"
"google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
@ -19,6 +16,7 @@ import (
// MarshalOptions configures the marshaler. // MarshalOptions configures the marshaler.
// //
// Example usage: // Example usage:
//
// b, err := MarshalOptions{Deterministic: true}.Marshal(m) // b, err := MarshalOptions{Deterministic: true}.Marshal(m)
type MarshalOptions struct { type MarshalOptions struct {
pragma.NoUnkeyedLiterals pragma.NoUnkeyedLiterals
@ -104,7 +102,9 @@ func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
// otherwise it returns a non-nil empty buffer. // otherwise it returns a non-nil empty buffer.
// //
// This is to assist the edge-case where user-code does the following: // This is to assist the edge-case where user-code does the following:
//
// m1.OptionalBytes, _ = proto.Marshal(m2) // m1.OptionalBytes, _ = proto.Marshal(m2)
//
// where they expect the proto2 "optional_bytes" field to be populated // where they expect the proto2 "optional_bytes" field to be populated
// if any only if m2 is a valid message. // if any only if m2 is a valid message.
func emptyBytesForMessage(m Message) []byte { func emptyBytesForMessage(m Message) []byte {
@ -211,14 +211,15 @@ func (o MarshalOptions) marshalMessageSlow(b []byte, m protoreflect.Message) ([]
if messageset.IsMessageSet(m.Descriptor()) { if messageset.IsMessageSet(m.Descriptor()) {
return o.marshalMessageSet(b, m) return o.marshalMessageSet(b, m)
} }
// There are many choices for what order we visit fields in. The default one here fieldOrder := order.AnyFieldOrder
// is chosen for reasonable efficiency and simplicity given the protoreflect API. if o.Deterministic {
// It is not deterministic, since Message.Range does not return fields in any // TODO: This should use a more natural ordering like NumberFieldOrder,
// defined order. // but doing so breaks golden tests that make invalid assumption about
// // output stability of this implementation.
// When using deterministic serialization, we sort the known fields. fieldOrder = order.LegacyFieldOrder
}
var err error var err error
o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { order.RangeFields(m, fieldOrder, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
b, err = o.marshalField(b, fd, v) b, err = o.marshalField(b, fd, v)
return err == nil return err == nil
}) })
@ -229,27 +230,6 @@ func (o MarshalOptions) marshalMessageSlow(b []byte, m protoreflect.Message) ([]
return b, nil return b, nil
} }
// rangeFields visits fields in a defined order when deterministic serialization is enabled.
func (o MarshalOptions) rangeFields(m protoreflect.Message, f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
if !o.Deterministic {
m.Range(f)
return
}
var fds []protoreflect.FieldDescriptor
m.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
fds = append(fds, fd)
return true
})
sort.Slice(fds, func(a, b int) bool {
return fieldsort.Less(fds[a], fds[b])
})
for _, fd := range fds {
if !f(fd, m.Get(fd)) {
break
}
}
}
func (o MarshalOptions) marshalField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) { func (o MarshalOptions) marshalField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) {
switch { switch {
case fd.IsList(): case fd.IsList():
@ -292,8 +272,12 @@ func (o MarshalOptions) marshalList(b []byte, fd protoreflect.FieldDescriptor, l
func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) ([]byte, error) { func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) ([]byte, error) {
keyf := fd.MapKey() keyf := fd.MapKey()
valf := fd.MapValue() valf := fd.MapValue()
keyOrder := order.AnyKeyOrder
if o.Deterministic {
keyOrder = order.GenericKeyOrder
}
var err error var err error
o.rangeMap(mapv, keyf.Kind(), func(key protoreflect.MapKey, value protoreflect.Value) bool { order.RangeEntries(mapv, keyOrder, func(key protoreflect.MapKey, value protoreflect.Value) bool {
b = protowire.AppendTag(b, fd.Number(), protowire.BytesType) b = protowire.AppendTag(b, fd.Number(), protowire.BytesType)
var pos int var pos int
b, pos = appendSpeculativeLength(b) b, pos = appendSpeculativeLength(b)
@ -312,14 +296,6 @@ func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, ma
return b, err return b, err
} }
func (o MarshalOptions) rangeMap(mapv protoreflect.Map, kind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
if !o.Deterministic {
mapv.Range(f)
return
}
mapsort.Range(mapv, kind, f)
}
// When encoding length-prefixed fields, we speculatively set aside some number of bytes // When encoding length-prefixed fields, we speculatively set aside some number of bytes
// for the length, encode the data, and then encode the length (shifting the data if necessary // for the length, encode the data, and then encode the length (shifting the data if necessary
// to make room). // to make room).

View File

@ -10,7 +10,7 @@ import (
"reflect" "reflect"
"google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/encoding/protowire"
pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
// Equal reports whether two messages are equal. // Equal reports whether two messages are equal.
@ -33,6 +33,10 @@ func Equal(x, y Message) bool {
if x == nil || y == nil { if x == nil || y == nil {
return x == nil && y == nil return x == nil && y == nil
} }
if reflect.TypeOf(x).Kind() == reflect.Ptr && x == y {
// Avoid an expensive comparison if both inputs are identical pointers.
return true
}
mx := x.ProtoReflect() mx := x.ProtoReflect()
my := y.ProtoReflect() my := y.ProtoReflect()
if mx.IsValid() != my.IsValid() { if mx.IsValid() != my.IsValid() {
@ -42,14 +46,14 @@ func Equal(x, y Message) bool {
} }
// equalMessage compares two messages. // equalMessage compares two messages.
func equalMessage(mx, my pref.Message) bool { func equalMessage(mx, my protoreflect.Message) bool {
if mx.Descriptor() != my.Descriptor() { if mx.Descriptor() != my.Descriptor() {
return false return false
} }
nx := 0 nx := 0
equal := true equal := true
mx.Range(func(fd pref.FieldDescriptor, vx pref.Value) bool { mx.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool {
nx++ nx++
vy := my.Get(fd) vy := my.Get(fd)
equal = my.Has(fd) && equalField(fd, vx, vy) equal = my.Has(fd) && equalField(fd, vx, vy)
@ -59,7 +63,7 @@ func equalMessage(mx, my pref.Message) bool {
return false return false
} }
ny := 0 ny := 0
my.Range(func(fd pref.FieldDescriptor, vx pref.Value) bool { my.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool {
ny++ ny++
return true return true
}) })
@ -71,7 +75,7 @@ func equalMessage(mx, my pref.Message) bool {
} }
// equalField compares two fields. // equalField compares two fields.
func equalField(fd pref.FieldDescriptor, x, y pref.Value) bool { func equalField(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool {
switch { switch {
case fd.IsList(): case fd.IsList():
return equalList(fd, x.List(), y.List()) return equalList(fd, x.List(), y.List())
@ -83,12 +87,12 @@ func equalField(fd pref.FieldDescriptor, x, y pref.Value) bool {
} }
// equalMap compares two maps. // equalMap compares two maps.
func equalMap(fd pref.FieldDescriptor, x, y pref.Map) bool { func equalMap(fd protoreflect.FieldDescriptor, x, y protoreflect.Map) bool {
if x.Len() != y.Len() { if x.Len() != y.Len() {
return false return false
} }
equal := true equal := true
x.Range(func(k pref.MapKey, vx pref.Value) bool { x.Range(func(k protoreflect.MapKey, vx protoreflect.Value) bool {
vy := y.Get(k) vy := y.Get(k)
equal = y.Has(k) && equalValue(fd.MapValue(), vx, vy) equal = y.Has(k) && equalValue(fd.MapValue(), vx, vy)
return equal return equal
@ -97,7 +101,7 @@ func equalMap(fd pref.FieldDescriptor, x, y pref.Map) bool {
} }
// equalList compares two lists. // equalList compares two lists.
func equalList(fd pref.FieldDescriptor, x, y pref.List) bool { func equalList(fd protoreflect.FieldDescriptor, x, y protoreflect.List) bool {
if x.Len() != y.Len() { if x.Len() != y.Len() {
return false return false
} }
@ -110,19 +114,32 @@ func equalList(fd pref.FieldDescriptor, x, y pref.List) bool {
} }
// equalValue compares two singular values. // equalValue compares two singular values.
func equalValue(fd pref.FieldDescriptor, x, y pref.Value) bool { func equalValue(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool {
switch { switch fd.Kind() {
case fd.Message() != nil: case protoreflect.BoolKind:
return equalMessage(x.Message(), y.Message()) return x.Bool() == y.Bool()
case fd.Kind() == pref.BytesKind: case protoreflect.EnumKind:
return bytes.Equal(x.Bytes(), y.Bytes()) return x.Enum() == y.Enum()
case fd.Kind() == pref.FloatKind, fd.Kind() == pref.DoubleKind: case protoreflect.Int32Kind, protoreflect.Sint32Kind,
protoreflect.Int64Kind, protoreflect.Sint64Kind,
protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind:
return x.Int() == y.Int()
case protoreflect.Uint32Kind, protoreflect.Uint64Kind,
protoreflect.Fixed32Kind, protoreflect.Fixed64Kind:
return x.Uint() == y.Uint()
case protoreflect.FloatKind, protoreflect.DoubleKind:
fx := x.Float() fx := x.Float()
fy := y.Float() fy := y.Float()
if math.IsNaN(fx) || math.IsNaN(fy) { if math.IsNaN(fx) || math.IsNaN(fy) {
return math.IsNaN(fx) && math.IsNaN(fy) return math.IsNaN(fx) && math.IsNaN(fy)
} }
return fx == fy return fx == fy
case protoreflect.StringKind:
return x.String() == y.String()
case protoreflect.BytesKind:
return bytes.Equal(x.Bytes(), y.Bytes())
case protoreflect.MessageKind, protoreflect.GroupKind:
return equalMessage(x.Message(), y.Message())
default: default:
return x.Interface() == y.Interface() return x.Interface() == y.Interface()
} }
@ -130,7 +147,7 @@ func equalValue(fd pref.FieldDescriptor, x, y pref.Value) bool {
// equalUnknown compares unknown fields by direct comparison on the raw bytes // equalUnknown compares unknown fields by direct comparison on the raw bytes
// of each individual field number. // of each individual field number.
func equalUnknown(x, y pref.RawFields) bool { func equalUnknown(x, y protoreflect.RawFields) bool {
if len(x) != len(y) { if len(x) != len(y) {
return false return false
} }
@ -138,8 +155,8 @@ func equalUnknown(x, y pref.RawFields) bool {
return true return true
} }
mx := make(map[pref.FieldNumber]pref.RawFields) mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields)
my := make(map[pref.FieldNumber]pref.RawFields) my := make(map[protoreflect.FieldNumber]protoreflect.RawFields)
for len(x) > 0 { for len(x) > 0 {
fnum, _, n := protowire.ConsumeField(x) fnum, _, n := protowire.ConsumeField(x)
mx[fnum] = append(mx[fnum], x[:n]...) mx[fnum] = append(mx[fnum], x[:n]...)

View File

@ -9,6 +9,7 @@ import (
"google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/order"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
@ -28,8 +29,12 @@ func (o MarshalOptions) marshalMessageSet(b []byte, m protoreflect.Message) ([]b
if !flags.ProtoLegacy { if !flags.ProtoLegacy {
return b, errors.New("no support for message_set_wire_format") return b, errors.New("no support for message_set_wire_format")
} }
fieldOrder := order.AnyFieldOrder
if o.Deterministic {
fieldOrder = order.NumberFieldOrder
}
var err error var err error
o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { order.RangeFields(m, fieldOrder, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
b, err = o.marshalMessageSetField(b, fd, v) b, err = o.marshalMessageSetField(b, fd, v)
return err == nil return err == nil
}) })

View File

@ -32,3 +32,12 @@ var Error error
func init() { func init() {
Error = errors.Error Error = errors.Error
} }
// MessageName returns the full name of m.
// If m is nil, it returns an empty string.
func MessageName(m Message) protoreflect.FullName {
if m == nil {
return ""
}
return m.ProtoReflect().Descriptor().FullName()
}

View File

@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// The protoreflect build tag disables use of fast-path methods. // The protoreflect build tag disables use of fast-path methods.
//go:build !protoreflect
// +build !protoreflect // +build !protoreflect
package proto package proto

View File

@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// The protoreflect build tag disables use of fast-path methods. // The protoreflect build tag disables use of fast-path methods.
//go:build protoreflect
// +build protoreflect // +build protoreflect
package proto package proto

View File

@ -0,0 +1,276 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package protodesc provides functionality for converting
// FileDescriptorProto messages to/from protoreflect.FileDescriptor values.
//
// The google.protobuf.FileDescriptorProto is a protobuf message that describes
// the type information for a .proto file in a form that is easily serializable.
// The protoreflect.FileDescriptor is a more structured representation of
// the FileDescriptorProto message where references and remote dependencies
// can be directly followed.
package protodesc
import (
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/descriptorpb"
)
// Resolver is the resolver used by NewFile to resolve dependencies.
// The enums and messages provided must belong to some parent file,
// which is also registered.
//
// It is implemented by protoregistry.Files.
type Resolver interface {
FindFileByPath(string) (protoreflect.FileDescriptor, error)
FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
}
// FileOptions configures the construction of file descriptors.
type FileOptions struct {
pragma.NoUnkeyedLiterals
// AllowUnresolvable configures New to permissively allow unresolvable
// file, enum, or message dependencies. Unresolved dependencies are replaced
// by placeholder equivalents.
//
// The following dependencies may be left unresolved:
// • Resolving an imported file.
// • Resolving the type for a message field or extension field.
// If the kind of the field is unknown, then a placeholder is used for both
// the Enum and Message accessors on the protoreflect.FieldDescriptor.
// • Resolving an enum value set as the default for an optional enum field.
// If unresolvable, the protoreflect.FieldDescriptor.Default is set to the
// first value in the associated enum (or zero if the also enum dependency
// is also unresolvable). The protoreflect.FieldDescriptor.DefaultEnumValue
// is populated with a placeholder.
// • Resolving the extended message type for an extension field.
// • Resolving the input or output message type for a service method.
//
// If the unresolved dependency uses a relative name,
// then the placeholder will contain an invalid FullName with a "*." prefix,
// indicating that the starting prefix of the full name is unknown.
AllowUnresolvable bool
}
// NewFile creates a new protoreflect.FileDescriptor from the provided
// file descriptor message. See FileOptions.New for more information.
func NewFile(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
return FileOptions{}.New(fd, r)
}
// NewFiles creates a new protoregistry.Files from the provided
// FileDescriptorSet message. See FileOptions.NewFiles for more information.
func NewFiles(fd *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
return FileOptions{}.NewFiles(fd)
}
// New creates a new protoreflect.FileDescriptor from the provided
// file descriptor message. The file must represent a valid proto file according
// to protobuf semantics. The returned descriptor is a deep copy of the input.
//
// Any imported files, enum types, or message types referenced in the file are
// resolved using the provided registry. When looking up an import file path,
// the path must be unique. The newly created file descriptor is not registered
// back into the provided file registry.
func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
if r == nil {
r = (*protoregistry.Files)(nil) // empty resolver
}
// Handle the file descriptor content.
f := &filedesc.File{L2: &filedesc.FileL2{}}
switch fd.GetSyntax() {
case "proto2", "":
f.L1.Syntax = protoreflect.Proto2
case "proto3":
f.L1.Syntax = protoreflect.Proto3
default:
return nil, errors.New("invalid syntax: %q", fd.GetSyntax())
}
f.L1.Path = fd.GetName()
if f.L1.Path == "" {
return nil, errors.New("file path must be populated")
}
f.L1.Package = protoreflect.FullName(fd.GetPackage())
if !f.L1.Package.IsValid() && f.L1.Package != "" {
return nil, errors.New("invalid package: %q", f.L1.Package)
}
if opts := fd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.FileOptions)
f.L2.Options = func() protoreflect.ProtoMessage { return opts }
}
f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency()))
for _, i := range fd.GetPublicDependency() {
if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsPublic {
return nil, errors.New("invalid or duplicate public import index: %d", i)
}
f.L2.Imports[i].IsPublic = true
}
for _, i := range fd.GetWeakDependency() {
if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsWeak {
return nil, errors.New("invalid or duplicate weak import index: %d", i)
}
f.L2.Imports[i].IsWeak = true
}
imps := importSet{f.Path(): true}
for i, path := range fd.GetDependency() {
imp := &f.L2.Imports[i]
f, err := r.FindFileByPath(path)
if err == protoregistry.NotFound && (o.AllowUnresolvable || imp.IsWeak) {
f = filedesc.PlaceholderFile(path)
} else if err != nil {
return nil, errors.New("could not resolve import %q: %v", path, err)
}
imp.FileDescriptor = f
if imps[imp.Path()] {
return nil, errors.New("already imported %q", path)
}
imps[imp.Path()] = true
}
for i := range fd.GetDependency() {
imp := &f.L2.Imports[i]
imps.importPublic(imp.Imports())
}
// Handle source locations.
f.L2.Locations.File = f
for _, loc := range fd.GetSourceCodeInfo().GetLocation() {
var l protoreflect.SourceLocation
// TODO: Validate that the path points to an actual declaration?
l.Path = protoreflect.SourcePath(loc.GetPath())
s := loc.GetSpan()
switch len(s) {
case 3:
l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[0]), int(s[2])
case 4:
l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[2]), int(s[3])
default:
return nil, errors.New("invalid span: %v", s)
}
// TODO: Validate that the span information is sensible?
// See https://github.com/protocolbuffers/protobuf/issues/6378.
if false && (l.EndLine < l.StartLine || l.StartLine < 0 || l.StartColumn < 0 || l.EndColumn < 0 ||
(l.StartLine == l.EndLine && l.EndColumn <= l.StartColumn)) {
return nil, errors.New("invalid span: %v", s)
}
l.LeadingDetachedComments = loc.GetLeadingDetachedComments()
l.LeadingComments = loc.GetLeadingComments()
l.TrailingComments = loc.GetTrailingComments()
f.L2.Locations.List = append(f.L2.Locations.List, l)
}
// Step 1: Allocate and derive the names for all declarations.
// This copies all fields from the descriptor proto except:
// google.protobuf.FieldDescriptorProto.type_name
// google.protobuf.FieldDescriptorProto.default_value
// google.protobuf.FieldDescriptorProto.oneof_index
// google.protobuf.FieldDescriptorProto.extendee
// google.protobuf.MethodDescriptorProto.input
// google.protobuf.MethodDescriptorProto.output
var err error
sb := new(strs.Builder)
r1 := make(descsByName)
if f.L1.Enums.List, err = r1.initEnumDeclarations(fd.GetEnumType(), f, sb); err != nil {
return nil, err
}
if f.L1.Messages.List, err = r1.initMessagesDeclarations(fd.GetMessageType(), f, sb); err != nil {
return nil, err
}
if f.L1.Extensions.List, err = r1.initExtensionDeclarations(fd.GetExtension(), f, sb); err != nil {
return nil, err
}
if f.L1.Services.List, err = r1.initServiceDeclarations(fd.GetService(), f, sb); err != nil {
return nil, err
}
// Step 2: Resolve every dependency reference not handled by step 1.
r2 := &resolver{local: r1, remote: r, imports: imps, allowUnresolvable: o.AllowUnresolvable}
if err := r2.resolveMessageDependencies(f.L1.Messages.List, fd.GetMessageType()); err != nil {
return nil, err
}
if err := r2.resolveExtensionDependencies(f.L1.Extensions.List, fd.GetExtension()); err != nil {
return nil, err
}
if err := r2.resolveServiceDependencies(f.L1.Services.List, fd.GetService()); err != nil {
return nil, err
}
// Step 3: Validate every enum, message, and extension declaration.
if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil {
return nil, err
}
if err := validateMessageDeclarations(f.L1.Messages.List, fd.GetMessageType()); err != nil {
return nil, err
}
if err := validateExtensionDeclarations(f.L1.Extensions.List, fd.GetExtension()); err != nil {
return nil, err
}
return f, nil
}
type importSet map[string]bool
func (is importSet) importPublic(imps protoreflect.FileImports) {
for i := 0; i < imps.Len(); i++ {
if imp := imps.Get(i); imp.IsPublic {
is[imp.Path()] = true
is.importPublic(imp.Imports())
}
}
}
// NewFiles creates a new protoregistry.Files from the provided
// FileDescriptorSet message. The descriptor set must include only
// valid files according to protobuf semantics. The returned descriptors
// are a deep copy of the input.
func (o FileOptions) NewFiles(fds *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
files := make(map[string]*descriptorpb.FileDescriptorProto)
for _, fd := range fds.File {
if _, ok := files[fd.GetName()]; ok {
return nil, errors.New("file appears multiple times: %q", fd.GetName())
}
files[fd.GetName()] = fd
}
r := &protoregistry.Files{}
for _, fd := range files {
if err := o.addFileDeps(r, fd, files); err != nil {
return nil, err
}
}
return r, nil
}
func (o FileOptions) addFileDeps(r *protoregistry.Files, fd *descriptorpb.FileDescriptorProto, files map[string]*descriptorpb.FileDescriptorProto) error {
// Set the entry to nil while descending into a file's dependencies to detect cycles.
files[fd.GetName()] = nil
for _, dep := range fd.Dependency {
depfd, ok := files[dep]
if depfd == nil {
if ok {
return errors.New("import cycle in file: %q", dep)
}
continue
}
if err := o.addFileDeps(r, depfd, files); err != nil {
return err
}
}
// Delete the entry once dependencies are processed.
delete(files, fd.GetName())
f, err := o.New(fd, r)
if err != nil {
return err
}
return r.RegisterFile(f)
}

View File

@ -0,0 +1,248 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package protodesc
import (
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
)
type descsByName map[protoreflect.FullName]protoreflect.Descriptor
func (r descsByName) initEnumDeclarations(eds []*descriptorpb.EnumDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (es []filedesc.Enum, err error) {
es = make([]filedesc.Enum, len(eds)) // allocate up-front to ensure stable pointers
for i, ed := range eds {
e := &es[i]
e.L2 = new(filedesc.EnumL2)
if e.L0, err = r.makeBase(e, parent, ed.GetName(), i, sb); err != nil {
return nil, err
}
if opts := ed.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.EnumOptions)
e.L2.Options = func() protoreflect.ProtoMessage { return opts }
}
for _, s := range ed.GetReservedName() {
e.L2.ReservedNames.List = append(e.L2.ReservedNames.List, protoreflect.Name(s))
}
for _, rr := range ed.GetReservedRange() {
e.L2.ReservedRanges.List = append(e.L2.ReservedRanges.List, [2]protoreflect.EnumNumber{
protoreflect.EnumNumber(rr.GetStart()),
protoreflect.EnumNumber(rr.GetEnd()),
})
}
if e.L2.Values.List, err = r.initEnumValuesFromDescriptorProto(ed.GetValue(), e, sb); err != nil {
return nil, err
}
}
return es, nil
}
func (r descsByName) initEnumValuesFromDescriptorProto(vds []*descriptorpb.EnumValueDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (vs []filedesc.EnumValue, err error) {
vs = make([]filedesc.EnumValue, len(vds)) // allocate up-front to ensure stable pointers
for i, vd := range vds {
v := &vs[i]
if v.L0, err = r.makeBase(v, parent, vd.GetName(), i, sb); err != nil {
return nil, err
}
if opts := vd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.EnumValueOptions)
v.L1.Options = func() protoreflect.ProtoMessage { return opts }
}
v.L1.Number = protoreflect.EnumNumber(vd.GetNumber())
}
return vs, nil
}
func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Message, err error) {
ms = make([]filedesc.Message, len(mds)) // allocate up-front to ensure stable pointers
for i, md := range mds {
m := &ms[i]
m.L2 = new(filedesc.MessageL2)
if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
return nil, err
}
if opts := md.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.MessageOptions)
m.L2.Options = func() protoreflect.ProtoMessage { return opts }
m.L1.IsMapEntry = opts.GetMapEntry()
m.L1.IsMessageSet = opts.GetMessageSetWireFormat()
}
for _, s := range md.GetReservedName() {
m.L2.ReservedNames.List = append(m.L2.ReservedNames.List, protoreflect.Name(s))
}
for _, rr := range md.GetReservedRange() {
m.L2.ReservedRanges.List = append(m.L2.ReservedRanges.List, [2]protoreflect.FieldNumber{
protoreflect.FieldNumber(rr.GetStart()),
protoreflect.FieldNumber(rr.GetEnd()),
})
}
for _, xr := range md.GetExtensionRange() {
m.L2.ExtensionRanges.List = append(m.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{
protoreflect.FieldNumber(xr.GetStart()),
protoreflect.FieldNumber(xr.GetEnd()),
})
var optsFunc func() protoreflect.ProtoMessage
if opts := xr.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.ExtensionRangeOptions)
optsFunc = func() protoreflect.ProtoMessage { return opts }
}
m.L2.ExtensionRangeOptions = append(m.L2.ExtensionRangeOptions, optsFunc)
}
if m.L2.Fields.List, err = r.initFieldsFromDescriptorProto(md.GetField(), m, sb); err != nil {
return nil, err
}
if m.L2.Oneofs.List, err = r.initOneofsFromDescriptorProto(md.GetOneofDecl(), m, sb); err != nil {
return nil, err
}
if m.L1.Enums.List, err = r.initEnumDeclarations(md.GetEnumType(), m, sb); err != nil {
return nil, err
}
if m.L1.Messages.List, err = r.initMessagesDeclarations(md.GetNestedType(), m, sb); err != nil {
return nil, err
}
if m.L1.Extensions.List, err = r.initExtensionDeclarations(md.GetExtension(), m, sb); err != nil {
return nil, err
}
}
return ms, nil
}
func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (fs []filedesc.Field, err error) {
fs = make([]filedesc.Field, len(fds)) // allocate up-front to ensure stable pointers
for i, fd := range fds {
f := &fs[i]
if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil {
return nil, err
}
f.L1.IsProto3Optional = fd.GetProto3Optional()
if opts := fd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
f.L1.Options = func() protoreflect.ProtoMessage { return opts }
f.L1.IsWeak = opts.GetWeak()
f.L1.HasPacked = opts.Packed != nil
f.L1.IsPacked = opts.GetPacked()
}
f.L1.Number = protoreflect.FieldNumber(fd.GetNumber())
f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel())
if fd.Type != nil {
f.L1.Kind = protoreflect.Kind(fd.GetType())
}
if fd.JsonName != nil {
f.L1.StringName.InitJSON(fd.GetJsonName())
}
}
return fs, nil
}
func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (os []filedesc.Oneof, err error) {
os = make([]filedesc.Oneof, len(ods)) // allocate up-front to ensure stable pointers
for i, od := range ods {
o := &os[i]
if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil {
return nil, err
}
if opts := od.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.OneofOptions)
o.L1.Options = func() protoreflect.ProtoMessage { return opts }
}
}
return os, nil
}
func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (xs []filedesc.Extension, err error) {
xs = make([]filedesc.Extension, len(xds)) // allocate up-front to ensure stable pointers
for i, xd := range xds {
x := &xs[i]
x.L2 = new(filedesc.ExtensionL2)
if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil {
return nil, err
}
if opts := xd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
x.L2.Options = func() protoreflect.ProtoMessage { return opts }
x.L2.IsPacked = opts.GetPacked()
}
x.L1.Number = protoreflect.FieldNumber(xd.GetNumber())
x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel())
if xd.Type != nil {
x.L1.Kind = protoreflect.Kind(xd.GetType())
}
if xd.JsonName != nil {
x.L2.StringName.InitJSON(xd.GetJsonName())
}
}
return xs, nil
}
func (r descsByName) initServiceDeclarations(sds []*descriptorpb.ServiceDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ss []filedesc.Service, err error) {
ss = make([]filedesc.Service, len(sds)) // allocate up-front to ensure stable pointers
for i, sd := range sds {
s := &ss[i]
s.L2 = new(filedesc.ServiceL2)
if s.L0, err = r.makeBase(s, parent, sd.GetName(), i, sb); err != nil {
return nil, err
}
if opts := sd.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.ServiceOptions)
s.L2.Options = func() protoreflect.ProtoMessage { return opts }
}
if s.L2.Methods.List, err = r.initMethodsFromDescriptorProto(sd.GetMethod(), s, sb); err != nil {
return nil, err
}
}
return ss, nil
}
func (r descsByName) initMethodsFromDescriptorProto(mds []*descriptorpb.MethodDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Method, err error) {
ms = make([]filedesc.Method, len(mds)) // allocate up-front to ensure stable pointers
for i, md := range mds {
m := &ms[i]
if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
return nil, err
}
if opts := md.GetOptions(); opts != nil {
opts = proto.Clone(opts).(*descriptorpb.MethodOptions)
m.L1.Options = func() protoreflect.ProtoMessage { return opts }
}
m.L1.IsStreamingClient = md.GetClientStreaming()
m.L1.IsStreamingServer = md.GetServerStreaming()
}
return ms, nil
}
func (r descsByName) makeBase(child, parent protoreflect.Descriptor, name string, idx int, sb *strs.Builder) (filedesc.BaseL0, error) {
if !protoreflect.Name(name).IsValid() {
return filedesc.BaseL0{}, errors.New("descriptor %q has an invalid nested name: %q", parent.FullName(), name)
}
// Derive the full name of the child.
// Note that enum values are a sibling to the enum parent in the namespace.
var fullName protoreflect.FullName
if _, ok := parent.(protoreflect.EnumDescriptor); ok {
fullName = sb.AppendFullName(parent.FullName().Parent(), protoreflect.Name(name))
} else {
fullName = sb.AppendFullName(parent.FullName(), protoreflect.Name(name))
}
if _, ok := r[fullName]; ok {
return filedesc.BaseL0{}, errors.New("descriptor %q already declared", fullName)
}
r[fullName] = child
// TODO: Verify that the full name does not already exist in the resolver?
// This is not as critical since most usages of NewFile will register
// the created file back into the registry, which will perform this check.
return filedesc.BaseL0{
FullName: fullName,
ParentFile: parent.ParentFile().(*filedesc.File),
Parent: parent,
Index: idx,
}, nil
}

View File

@ -0,0 +1,286 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package protodesc
import (
"google.golang.org/protobuf/internal/encoding/defval"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/descriptorpb"
)
// resolver is a wrapper around a local registry of declarations within the file
// and the remote resolver. The remote resolver is restricted to only return
// descriptors that have been imported.
type resolver struct {
local descsByName
remote Resolver
imports importSet
allowUnresolvable bool
}
func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) (err error) {
for i, md := range mds {
m := &ms[i]
for j, fd := range md.GetField() {
f := &m.L2.Fields.List[j]
if f.L1.Cardinality == protoreflect.Required {
m.L2.RequiredNumbers.List = append(m.L2.RequiredNumbers.List, f.L1.Number)
}
if fd.OneofIndex != nil {
k := int(fd.GetOneofIndex())
if !(0 <= k && k < len(md.GetOneofDecl())) {
return errors.New("message field %q has an invalid oneof index: %d", f.FullName(), k)
}
o := &m.L2.Oneofs.List[k]
f.L1.ContainingOneof = o
o.L1.Fields.List = append(o.L1.Fields.List, f)
}
if f.L1.Kind, f.L1.Enum, f.L1.Message, err = r.findTarget(f.Kind(), f.Parent().FullName(), partialName(fd.GetTypeName()), f.IsWeak()); err != nil {
return errors.New("message field %q cannot resolve type: %v", f.FullName(), err)
}
if fd.DefaultValue != nil {
v, ev, err := unmarshalDefault(fd.GetDefaultValue(), f, r.allowUnresolvable)
if err != nil {
return errors.New("message field %q has invalid default: %v", f.FullName(), err)
}
f.L1.Default = filedesc.DefaultValue(v, ev)
}
}
if err := r.resolveMessageDependencies(m.L1.Messages.List, md.GetNestedType()); err != nil {
return err
}
if err := r.resolveExtensionDependencies(m.L1.Extensions.List, md.GetExtension()); err != nil {
return err
}
}
return nil
}
func (r *resolver) resolveExtensionDependencies(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) (err error) {
for i, xd := range xds {
x := &xs[i]
if x.L1.Extendee, err = r.findMessageDescriptor(x.Parent().FullName(), partialName(xd.GetExtendee()), false); err != nil {
return errors.New("extension field %q cannot resolve extendee: %v", x.FullName(), err)
}
if x.L1.Kind, x.L2.Enum, x.L2.Message, err = r.findTarget(x.Kind(), x.Parent().FullName(), partialName(xd.GetTypeName()), false); err != nil {
return errors.New("extension field %q cannot resolve type: %v", x.FullName(), err)
}
if xd.DefaultValue != nil {
v, ev, err := unmarshalDefault(xd.GetDefaultValue(), x, r.allowUnresolvable)
if err != nil {
return errors.New("extension field %q has invalid default: %v", x.FullName(), err)
}
x.L2.Default = filedesc.DefaultValue(v, ev)
}
}
return nil
}
func (r *resolver) resolveServiceDependencies(ss []filedesc.Service, sds []*descriptorpb.ServiceDescriptorProto) (err error) {
for i, sd := range sds {
s := &ss[i]
for j, md := range sd.GetMethod() {
m := &s.L2.Methods.List[j]
m.L1.Input, err = r.findMessageDescriptor(m.Parent().FullName(), partialName(md.GetInputType()), false)
if err != nil {
return errors.New("service method %q cannot resolve input: %v", m.FullName(), err)
}
m.L1.Output, err = r.findMessageDescriptor(s.FullName(), partialName(md.GetOutputType()), false)
if err != nil {
return errors.New("service method %q cannot resolve output: %v", m.FullName(), err)
}
}
}
return nil
}
// findTarget finds an enum or message descriptor if k is an enum, message,
// group, or unknown. If unknown, and the name could be resolved, the kind
// returned kind is set based on the type of the resolved descriptor.
func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.Kind, protoreflect.EnumDescriptor, protoreflect.MessageDescriptor, error) {
switch k {
case protoreflect.EnumKind:
ed, err := r.findEnumDescriptor(scope, ref, isWeak)
if err != nil {
return 0, nil, nil, err
}
return k, ed, nil, nil
case protoreflect.MessageKind, protoreflect.GroupKind:
md, err := r.findMessageDescriptor(scope, ref, isWeak)
if err != nil {
return 0, nil, nil, err
}
return k, nil, md, nil
case 0:
// Handle unspecified kinds (possible with parsers that operate
// on a per-file basis without knowledge of dependencies).
d, err := r.findDescriptor(scope, ref)
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
return k, filedesc.PlaceholderEnum(ref.FullName()), filedesc.PlaceholderMessage(ref.FullName()), nil
} else if err == protoregistry.NotFound {
return 0, nil, nil, errors.New("%q not found", ref.FullName())
} else if err != nil {
return 0, nil, nil, err
}
switch d := d.(type) {
case protoreflect.EnumDescriptor:
return protoreflect.EnumKind, d, nil, nil
case protoreflect.MessageDescriptor:
return protoreflect.MessageKind, nil, d, nil
default:
return 0, nil, nil, errors.New("unknown kind")
}
default:
if ref != "" {
return 0, nil, nil, errors.New("target name cannot be specified for %v", k)
}
if !k.IsValid() {
return 0, nil, nil, errors.New("invalid kind: %d", k)
}
return k, nil, nil, nil
}
}
// findDescriptor finds the descriptor by name,
// which may be a relative name within some scope.
//
// Suppose the scope was "fizz.buzz" and the reference was "Foo.Bar",
// then the following full names are searched:
// - fizz.buzz.Foo.Bar
// - fizz.Foo.Bar
// - Foo.Bar
func (r *resolver) findDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.Descriptor, error) {
if !ref.IsValid() {
return nil, errors.New("invalid name reference: %q", ref)
}
if ref.IsFull() {
scope, ref = "", ref[1:]
}
var foundButNotImported protoreflect.Descriptor
for {
// Derive the full name to search.
s := protoreflect.FullName(ref)
if scope != "" {
s = scope + "." + s
}
// Check the current file for the descriptor.
if d, ok := r.local[s]; ok {
return d, nil
}
// Check the remote registry for the descriptor.
d, err := r.remote.FindDescriptorByName(s)
if err == nil {
// Only allow descriptors covered by one of the imports.
if r.imports[d.ParentFile().Path()] {
return d, nil
}
foundButNotImported = d
} else if err != protoregistry.NotFound {
return nil, errors.Wrap(err, "%q", s)
}
// Continue on at a higher level of scoping.
if scope == "" {
if d := foundButNotImported; d != nil {
return nil, errors.New("resolved %q, but %q is not imported", d.FullName(), d.ParentFile().Path())
}
return nil, protoregistry.NotFound
}
scope = scope.Parent()
}
}
func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.EnumDescriptor, error) {
d, err := r.findDescriptor(scope, ref)
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
return filedesc.PlaceholderEnum(ref.FullName()), nil
} else if err == protoregistry.NotFound {
return nil, errors.New("%q not found", ref.FullName())
} else if err != nil {
return nil, err
}
ed, ok := d.(protoreflect.EnumDescriptor)
if !ok {
return nil, errors.New("resolved %q, but it is not an enum", d.FullName())
}
return ed, nil
}
func (r *resolver) findMessageDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.MessageDescriptor, error) {
d, err := r.findDescriptor(scope, ref)
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
return filedesc.PlaceholderMessage(ref.FullName()), nil
} else if err == protoregistry.NotFound {
return nil, errors.New("%q not found", ref.FullName())
} else if err != nil {
return nil, err
}
md, ok := d.(protoreflect.MessageDescriptor)
if !ok {
return nil, errors.New("resolved %q, but it is not an message", d.FullName())
}
return md, nil
}
// partialName is the partial name. A leading dot means that the name is full,
// otherwise the name is relative to some current scope.
// See google.protobuf.FieldDescriptorProto.type_name.
type partialName string
func (s partialName) IsFull() bool {
return len(s) > 0 && s[0] == '.'
}
func (s partialName) IsValid() bool {
if s.IsFull() {
return protoreflect.FullName(s[1:]).IsValid()
}
return protoreflect.FullName(s).IsValid()
}
const unknownPrefix = "*."
// FullName converts the partial name to a full name on a best-effort basis.
// If relative, it creates an invalid full name, using a "*." prefix
// to indicate that the start of the full name is unknown.
func (s partialName) FullName() protoreflect.FullName {
if s.IsFull() {
return protoreflect.FullName(s[1:])
}
return protoreflect.FullName(unknownPrefix + s)
}
func unmarshalDefault(s string, fd protoreflect.FieldDescriptor, allowUnresolvable bool) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) {
var evs protoreflect.EnumValueDescriptors
if fd.Enum() != nil {
evs = fd.Enum().Values()
}
v, ev, err := defval.Unmarshal(s, fd.Kind(), evs, defval.Descriptor)
if err != nil && allowUnresolvable && evs != nil && protoreflect.Name(s).IsValid() {
v = protoreflect.ValueOfEnum(0)
if evs.Len() > 0 {
v = protoreflect.ValueOfEnum(evs.Get(0).Number())
}
ev = filedesc.PlaceholderEnumValue(fd.Enum().FullName().Parent().Append(protoreflect.Name(s)))
} else if err != nil {
return v, ev, err
}
if fd.Syntax() == protoreflect.Proto3 {
return v, ev, errors.New("cannot be specified under proto3 semantics")
}
if fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind || fd.Cardinality() == protoreflect.Repeated {
return v, ev, errors.New("cannot be specified on composite types")
}
return v, ev, nil
}

View File

@ -0,0 +1,374 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package protodesc
import (
"strings"
"unicode"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/filedesc"
"google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/internal/genid"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
)
func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescriptorProto) error {
for i, ed := range eds {
e := &es[i]
if err := e.L2.ReservedNames.CheckValid(); err != nil {
return errors.New("enum %q reserved names has %v", e.FullName(), err)
}
if err := e.L2.ReservedRanges.CheckValid(); err != nil {
return errors.New("enum %q reserved ranges has %v", e.FullName(), err)
}
if len(ed.GetValue()) == 0 {
return errors.New("enum %q must contain at least one value declaration", e.FullName())
}
allowAlias := ed.GetOptions().GetAllowAlias()
foundAlias := false
for i := 0; i < e.Values().Len(); i++ {
v1 := e.Values().Get(i)
if v2 := e.Values().ByNumber(v1.Number()); v1 != v2 {
foundAlias = true
if !allowAlias {
return errors.New("enum %q has conflicting non-aliased values on number %d: %q with %q", e.FullName(), v1.Number(), v1.Name(), v2.Name())
}
}
}
if allowAlias && !foundAlias {
return errors.New("enum %q allows aliases, but none were found", e.FullName())
}
if e.Syntax() == protoreflect.Proto3 {
if v := e.Values().Get(0); v.Number() != 0 {
return errors.New("enum %q using proto3 semantics must have zero number for the first value", v.FullName())
}
// Verify that value names in proto3 do not conflict if the
// case-insensitive prefix is removed.
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:4991-5055
names := map[string]protoreflect.EnumValueDescriptor{}
prefix := strings.Replace(strings.ToLower(string(e.Name())), "_", "", -1)
for i := 0; i < e.Values().Len(); i++ {
v1 := e.Values().Get(i)
s := strs.EnumValueName(strs.TrimEnumPrefix(string(v1.Name()), prefix))
if v2, ok := names[s]; ok && v1.Number() != v2.Number() {
return errors.New("enum %q using proto3 semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name())
}
names[s] = v1
}
}
for j, vd := range ed.GetValue() {
v := &e.L2.Values.List[j]
if vd.Number == nil {
return errors.New("enum value %q must have a specified number", v.FullName())
}
if e.L2.ReservedNames.Has(v.Name()) {
return errors.New("enum value %q must not use reserved name", v.FullName())
}
if e.L2.ReservedRanges.Has(v.Number()) {
return errors.New("enum value %q must not use reserved number %d", v.FullName(), v.Number())
}
}
}
return nil
}
func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error {
for i, md := range mds {
m := &ms[i]
// Handle the message descriptor itself.
isMessageSet := md.GetOptions().GetMessageSetWireFormat()
if err := m.L2.ReservedNames.CheckValid(); err != nil {
return errors.New("message %q reserved names has %v", m.FullName(), err)
}
if err := m.L2.ReservedRanges.CheckValid(isMessageSet); err != nil {
return errors.New("message %q reserved ranges has %v", m.FullName(), err)
}
if err := m.L2.ExtensionRanges.CheckValid(isMessageSet); err != nil {
return errors.New("message %q extension ranges has %v", m.FullName(), err)
}
if err := (*filedesc.FieldRanges).CheckOverlap(&m.L2.ReservedRanges, &m.L2.ExtensionRanges); err != nil {
return errors.New("message %q reserved and extension ranges has %v", m.FullName(), err)
}
for i := 0; i < m.Fields().Len(); i++ {
f1 := m.Fields().Get(i)
if f2 := m.Fields().ByNumber(f1.Number()); f1 != f2 {
return errors.New("message %q has conflicting fields: %q with %q", m.FullName(), f1.Name(), f2.Name())
}
}
if isMessageSet && !flags.ProtoLegacy {
return errors.New("message %q is a MessageSet, which is a legacy proto1 feature that is no longer supported", m.FullName())
}
if isMessageSet && (m.Syntax() != protoreflect.Proto2 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) {
return errors.New("message %q is an invalid proto1 MessageSet", m.FullName())
}
if m.Syntax() == protoreflect.Proto3 {
if m.ExtensionRanges().Len() > 0 {
return errors.New("message %q using proto3 semantics cannot have extension ranges", m.FullName())
}
// Verify that field names in proto3 do not conflict if lowercased
// with all underscores removed.
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:5830-5847
names := map[string]protoreflect.FieldDescriptor{}
for i := 0; i < m.Fields().Len(); i++ {
f1 := m.Fields().Get(i)
s := strings.Replace(strings.ToLower(string(f1.Name())), "_", "", -1)
if f2, ok := names[s]; ok {
return errors.New("message %q using proto3 semantics has conflict: %q with %q", m.FullName(), f1.Name(), f2.Name())
}
names[s] = f1
}
}
for j, fd := range md.GetField() {
f := &m.L2.Fields.List[j]
if m.L2.ReservedNames.Has(f.Name()) {
return errors.New("message field %q must not use reserved name", f.FullName())
}
if !f.Number().IsValid() {
return errors.New("message field %q has an invalid number: %d", f.FullName(), f.Number())
}
if !f.Cardinality().IsValid() {
return errors.New("message field %q has an invalid cardinality: %d", f.FullName(), f.Cardinality())
}
if m.L2.ReservedRanges.Has(f.Number()) {
return errors.New("message field %q must not use reserved number %d", f.FullName(), f.Number())
}
if m.L2.ExtensionRanges.Has(f.Number()) {
return errors.New("message field %q with number %d in extension range", f.FullName(), f.Number())
}
if fd.Extendee != nil {
return errors.New("message field %q may not have extendee: %q", f.FullName(), fd.GetExtendee())
}
if f.L1.IsProto3Optional {
if f.Syntax() != protoreflect.Proto3 {
return errors.New("message field %q under proto3 optional semantics must be specified in the proto3 syntax", f.FullName())
}
if f.Cardinality() != protoreflect.Optional {
return errors.New("message field %q under proto3 optional semantics must have optional cardinality", f.FullName())
}
if f.ContainingOneof() != nil && f.ContainingOneof().Fields().Len() != 1 {
return errors.New("message field %q under proto3 optional semantics must be within a single element oneof", f.FullName())
}
}
if f.IsWeak() && !flags.ProtoLegacy {
return errors.New("message field %q is a weak field, which is a legacy proto1 feature that is no longer supported", f.FullName())
}
if f.IsWeak() && (f.Syntax() != protoreflect.Proto2 || !isOptionalMessage(f) || f.ContainingOneof() != nil) {
return errors.New("message field %q may only be weak for an optional message", f.FullName())
}
if f.IsPacked() && !isPackable(f) {
return errors.New("message field %q is not packable", f.FullName())
}
if err := checkValidGroup(f); err != nil {
return errors.New("message field %q is an invalid group: %v", f.FullName(), err)
}
if err := checkValidMap(f); err != nil {
return errors.New("message field %q is an invalid map: %v", f.FullName(), err)
}
if f.Syntax() == protoreflect.Proto3 {
if f.Cardinality() == protoreflect.Required {
return errors.New("message field %q using proto3 semantics cannot be required", f.FullName())
}
if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().Syntax() != protoreflect.Proto3 {
return errors.New("message field %q using proto3 semantics may only depend on a proto3 enum", f.FullName())
}
}
}
seenSynthetic := false // synthetic oneofs for proto3 optional must come after real oneofs
for j := range md.GetOneofDecl() {
o := &m.L2.Oneofs.List[j]
if o.Fields().Len() == 0 {
return errors.New("message oneof %q must contain at least one field declaration", o.FullName())
}
if n := o.Fields().Len(); n-1 != (o.Fields().Get(n-1).Index() - o.Fields().Get(0).Index()) {
return errors.New("message oneof %q must have consecutively declared fields", o.FullName())
}
if o.IsSynthetic() {
seenSynthetic = true
continue
}
if !o.IsSynthetic() && seenSynthetic {
return errors.New("message oneof %q must be declared before synthetic oneofs", o.FullName())
}
for i := 0; i < o.Fields().Len(); i++ {
f := o.Fields().Get(i)
if f.Cardinality() != protoreflect.Optional {
return errors.New("message field %q belongs in a oneof and must be optional", f.FullName())
}
if f.IsWeak() {
return errors.New("message field %q belongs in a oneof and must not be a weak reference", f.FullName())
}
}
}
if err := validateEnumDeclarations(m.L1.Enums.List, md.GetEnumType()); err != nil {
return err
}
if err := validateMessageDeclarations(m.L1.Messages.List, md.GetNestedType()); err != nil {
return err
}
if err := validateExtensionDeclarations(m.L1.Extensions.List, md.GetExtension()); err != nil {
return err
}
}
return nil
}
func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error {
for i, xd := range xds {
x := &xs[i]
// NOTE: Avoid using the IsValid method since extensions to MessageSet
// may have a field number higher than normal. This check only verifies
// that the number is not negative or reserved. We check again later
// if we know that the extendee is definitely not a MessageSet.
if n := x.Number(); n < 0 || (protowire.FirstReservedNumber <= n && n <= protowire.LastReservedNumber) {
return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
}
if !x.Cardinality().IsValid() || x.Cardinality() == protoreflect.Required {
return errors.New("extension field %q has an invalid cardinality: %d", x.FullName(), x.Cardinality())
}
if xd.JsonName != nil {
// A bug in older versions of protoc would always populate the
// "json_name" option for extensions when it is meaningless.
// When it did so, it would always use the camel-cased field name.
if xd.GetJsonName() != strs.JSONCamelCase(string(x.Name())) {
return errors.New("extension field %q may not have an explicitly set JSON name: %q", x.FullName(), xd.GetJsonName())
}
}
if xd.OneofIndex != nil {
return errors.New("extension field %q may not be part of a oneof", x.FullName())
}
if md := x.ContainingMessage(); !md.IsPlaceholder() {
if !md.ExtensionRanges().Has(x.Number()) {
return errors.New("extension field %q extends %q with non-extension field number: %d", x.FullName(), md.FullName(), x.Number())
}
isMessageSet := md.Options().(*descriptorpb.MessageOptions).GetMessageSetWireFormat()
if isMessageSet && !isOptionalMessage(x) {
return errors.New("extension field %q extends MessageSet and must be an optional message", x.FullName())
}
if !isMessageSet && !x.Number().IsValid() {
return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
}
}
if xd.GetOptions().GetWeak() {
return errors.New("extension field %q cannot be a weak reference", x.FullName())
}
if x.IsPacked() && !isPackable(x) {
return errors.New("extension field %q is not packable", x.FullName())
}
if err := checkValidGroup(x); err != nil {
return errors.New("extension field %q is an invalid group: %v", x.FullName(), err)
}
if md := x.Message(); md != nil && md.IsMapEntry() {
return errors.New("extension field %q cannot be a map entry", x.FullName())
}
if x.Syntax() == protoreflect.Proto3 {
switch x.ContainingMessage().FullName() {
case (*descriptorpb.FileOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.EnumOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.EnumValueOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.MessageOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.FieldOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.OneofOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.ExtensionRangeOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.ServiceOptions)(nil).ProtoReflect().Descriptor().FullName():
case (*descriptorpb.MethodOptions)(nil).ProtoReflect().Descriptor().FullName():
default:
return errors.New("extension field %q cannot be declared in proto3 unless extended descriptor options", x.FullName())
}
}
}
return nil
}
// isOptionalMessage reports whether this is an optional message.
// If the kind is unknown, it is assumed to be a message.
func isOptionalMessage(fd protoreflect.FieldDescriptor) bool {
return (fd.Kind() == 0 || fd.Kind() == protoreflect.MessageKind) && fd.Cardinality() == protoreflect.Optional
}
// isPackable checks whether the pack option can be specified.
func isPackable(fd protoreflect.FieldDescriptor) bool {
switch fd.Kind() {
case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
return false
}
return fd.IsList()
}
// checkValidGroup reports whether fd is a valid group according to the same
// rules that protoc imposes.
func checkValidGroup(fd protoreflect.FieldDescriptor) error {
md := fd.Message()
switch {
case fd.Kind() != protoreflect.GroupKind:
return nil
case fd.Syntax() != protoreflect.Proto2:
return errors.New("invalid under proto2 semantics")
case md == nil || md.IsPlaceholder():
return errors.New("message must be resolvable")
case fd.FullName().Parent() != md.FullName().Parent():
return errors.New("message and field must be declared in the same scope")
case !unicode.IsUpper(rune(md.Name()[0])):
return errors.New("message name must start with an uppercase")
case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))):
return errors.New("field name must be lowercased form of the message name")
}
return nil
}
// checkValidMap checks whether the field is a valid map according to the same
// rules that protoc imposes.
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:6045-6115
func checkValidMap(fd protoreflect.FieldDescriptor) error {
md := fd.Message()
switch {
case md == nil || !md.IsMapEntry():
return nil
case fd.FullName().Parent() != md.FullName().Parent():
return errors.New("message and field must be declared in the same scope")
case md.Name() != protoreflect.Name(strs.MapEntryName(string(fd.Name()))):
return errors.New("incorrect implicit map entry name")
case fd.Cardinality() != protoreflect.Repeated:
return errors.New("field must be repeated")
case md.Fields().Len() != 2:
return errors.New("message must have exactly two fields")
case md.ExtensionRanges().Len() > 0:
return errors.New("message must not have any extension ranges")
case md.Enums().Len()+md.Messages().Len()+md.Extensions().Len() > 0:
return errors.New("message must not have any nested declarations")
}
kf := md.Fields().Get(0)
vf := md.Fields().Get(1)
switch {
case kf.Name() != genid.MapEntry_Key_field_name || kf.Number() != genid.MapEntry_Key_field_number || kf.Cardinality() != protoreflect.Optional || kf.ContainingOneof() != nil || kf.HasDefault():
return errors.New("invalid key field")
case vf.Name() != genid.MapEntry_Value_field_name || vf.Number() != genid.MapEntry_Value_field_number || vf.Cardinality() != protoreflect.Optional || vf.ContainingOneof() != nil || vf.HasDefault():
return errors.New("invalid value field")
}
switch kf.Kind() {
case protoreflect.BoolKind: // bool
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: // int32
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: // int64
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: // uint32
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: // uint64
case protoreflect.StringKind: // string
default:
return errors.New("invalid key kind: %v", kf.Kind())
}
if e := vf.Enum(); e != nil && e.Values().Len() > 0 && e.Values().Get(0).Number() != 0 {
return errors.New("map enum value must have zero number for the first value")
}
return nil
}

View File

@ -0,0 +1,252 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package protodesc
import (
"fmt"
"strings"
"google.golang.org/protobuf/internal/encoding/defval"
"google.golang.org/protobuf/internal/strs"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
)
// ToFileDescriptorProto copies a protoreflect.FileDescriptor into a
// google.protobuf.FileDescriptorProto message.
func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto {
p := &descriptorpb.FileDescriptorProto{
Name: proto.String(file.Path()),
Options: proto.Clone(file.Options()).(*descriptorpb.FileOptions),
}
if file.Package() != "" {
p.Package = proto.String(string(file.Package()))
}
for i, imports := 0, file.Imports(); i < imports.Len(); i++ {
imp := imports.Get(i)
p.Dependency = append(p.Dependency, imp.Path())
if imp.IsPublic {
p.PublicDependency = append(p.PublicDependency, int32(i))
}
if imp.IsWeak {
p.WeakDependency = append(p.WeakDependency, int32(i))
}
}
for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ {
loc := locs.Get(i)
l := &descriptorpb.SourceCodeInfo_Location{}
l.Path = append(l.Path, loc.Path...)
if loc.StartLine == loc.EndLine {
l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndColumn)}
} else {
l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndLine), int32(loc.EndColumn)}
}
l.LeadingDetachedComments = append([]string(nil), loc.LeadingDetachedComments...)
if loc.LeadingComments != "" {
l.LeadingComments = proto.String(loc.LeadingComments)
}
if loc.TrailingComments != "" {
l.TrailingComments = proto.String(loc.TrailingComments)
}
if p.SourceCodeInfo == nil {
p.SourceCodeInfo = &descriptorpb.SourceCodeInfo{}
}
p.SourceCodeInfo.Location = append(p.SourceCodeInfo.Location, l)
}
for i, messages := 0, file.Messages(); i < messages.Len(); i++ {
p.MessageType = append(p.MessageType, ToDescriptorProto(messages.Get(i)))
}
for i, enums := 0, file.Enums(); i < enums.Len(); i++ {
p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
}
for i, services := 0, file.Services(); i < services.Len(); i++ {
p.Service = append(p.Service, ToServiceDescriptorProto(services.Get(i)))
}
for i, exts := 0, file.Extensions(); i < exts.Len(); i++ {
p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
}
if syntax := file.Syntax(); syntax != protoreflect.Proto2 {
p.Syntax = proto.String(file.Syntax().String())
}
return p
}
// ToDescriptorProto copies a protoreflect.MessageDescriptor into a
// google.protobuf.DescriptorProto message.
func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto {
p := &descriptorpb.DescriptorProto{
Name: proto.String(string(message.Name())),
Options: proto.Clone(message.Options()).(*descriptorpb.MessageOptions),
}
for i, fields := 0, message.Fields(); i < fields.Len(); i++ {
p.Field = append(p.Field, ToFieldDescriptorProto(fields.Get(i)))
}
for i, exts := 0, message.Extensions(); i < exts.Len(); i++ {
p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
}
for i, messages := 0, message.Messages(); i < messages.Len(); i++ {
p.NestedType = append(p.NestedType, ToDescriptorProto(messages.Get(i)))
}
for i, enums := 0, message.Enums(); i < enums.Len(); i++ {
p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
}
for i, xranges := 0, message.ExtensionRanges(); i < xranges.Len(); i++ {
xrange := xranges.Get(i)
p.ExtensionRange = append(p.ExtensionRange, &descriptorpb.DescriptorProto_ExtensionRange{
Start: proto.Int32(int32(xrange[0])),
End: proto.Int32(int32(xrange[1])),
Options: proto.Clone(message.ExtensionRangeOptions(i)).(*descriptorpb.ExtensionRangeOptions),
})
}
for i, oneofs := 0, message.Oneofs(); i < oneofs.Len(); i++ {
p.OneofDecl = append(p.OneofDecl, ToOneofDescriptorProto(oneofs.Get(i)))
}
for i, ranges := 0, message.ReservedRanges(); i < ranges.Len(); i++ {
rrange := ranges.Get(i)
p.ReservedRange = append(p.ReservedRange, &descriptorpb.DescriptorProto_ReservedRange{
Start: proto.Int32(int32(rrange[0])),
End: proto.Int32(int32(rrange[1])),
})
}
for i, names := 0, message.ReservedNames(); i < names.Len(); i++ {
p.ReservedName = append(p.ReservedName, string(names.Get(i)))
}
return p
}
// ToFieldDescriptorProto copies a protoreflect.FieldDescriptor into a
// google.protobuf.FieldDescriptorProto message.
func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto {
p := &descriptorpb.FieldDescriptorProto{
Name: proto.String(string(field.Name())),
Number: proto.Int32(int32(field.Number())),
Label: descriptorpb.FieldDescriptorProto_Label(field.Cardinality()).Enum(),
Options: proto.Clone(field.Options()).(*descriptorpb.FieldOptions),
}
if field.IsExtension() {
p.Extendee = fullNameOf(field.ContainingMessage())
}
if field.Kind().IsValid() {
p.Type = descriptorpb.FieldDescriptorProto_Type(field.Kind()).Enum()
}
if field.Enum() != nil {
p.TypeName = fullNameOf(field.Enum())
}
if field.Message() != nil {
p.TypeName = fullNameOf(field.Message())
}
if field.HasJSONName() {
// A bug in older versions of protoc would always populate the
// "json_name" option for extensions when it is meaningless.
// When it did so, it would always use the camel-cased field name.
if field.IsExtension() {
p.JsonName = proto.String(strs.JSONCamelCase(string(field.Name())))
} else {
p.JsonName = proto.String(field.JSONName())
}
}
if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() {
p.Proto3Optional = proto.Bool(true)
}
if field.HasDefault() {
def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor)
if err != nil && field.DefaultEnumValue() != nil {
def = string(field.DefaultEnumValue().Name()) // occurs for unresolved enum values
} else if err != nil {
panic(fmt.Sprintf("%v: %v", field.FullName(), err))
}
p.DefaultValue = proto.String(def)
}
if oneof := field.ContainingOneof(); oneof != nil {
p.OneofIndex = proto.Int32(int32(oneof.Index()))
}
return p
}
// ToOneofDescriptorProto copies a protoreflect.OneofDescriptor into a
// google.protobuf.OneofDescriptorProto message.
func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto {
return &descriptorpb.OneofDescriptorProto{
Name: proto.String(string(oneof.Name())),
Options: proto.Clone(oneof.Options()).(*descriptorpb.OneofOptions),
}
}
// ToEnumDescriptorProto copies a protoreflect.EnumDescriptor into a
// google.protobuf.EnumDescriptorProto message.
func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto {
p := &descriptorpb.EnumDescriptorProto{
Name: proto.String(string(enum.Name())),
Options: proto.Clone(enum.Options()).(*descriptorpb.EnumOptions),
}
for i, values := 0, enum.Values(); i < values.Len(); i++ {
p.Value = append(p.Value, ToEnumValueDescriptorProto(values.Get(i)))
}
for i, ranges := 0, enum.ReservedRanges(); i < ranges.Len(); i++ {
rrange := ranges.Get(i)
p.ReservedRange = append(p.ReservedRange, &descriptorpb.EnumDescriptorProto_EnumReservedRange{
Start: proto.Int32(int32(rrange[0])),
End: proto.Int32(int32(rrange[1])),
})
}
for i, names := 0, enum.ReservedNames(); i < names.Len(); i++ {
p.ReservedName = append(p.ReservedName, string(names.Get(i)))
}
return p
}
// ToEnumValueDescriptorProto copies a protoreflect.EnumValueDescriptor into a
// google.protobuf.EnumValueDescriptorProto message.
func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto {
return &descriptorpb.EnumValueDescriptorProto{
Name: proto.String(string(value.Name())),
Number: proto.Int32(int32(value.Number())),
Options: proto.Clone(value.Options()).(*descriptorpb.EnumValueOptions),
}
}
// ToServiceDescriptorProto copies a protoreflect.ServiceDescriptor into a
// google.protobuf.ServiceDescriptorProto message.
func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto {
p := &descriptorpb.ServiceDescriptorProto{
Name: proto.String(string(service.Name())),
Options: proto.Clone(service.Options()).(*descriptorpb.ServiceOptions),
}
for i, methods := 0, service.Methods(); i < methods.Len(); i++ {
p.Method = append(p.Method, ToMethodDescriptorProto(methods.Get(i)))
}
return p
}
// ToMethodDescriptorProto copies a protoreflect.MethodDescriptor into a
// google.protobuf.MethodDescriptorProto message.
func ToMethodDescriptorProto(method protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto {
p := &descriptorpb.MethodDescriptorProto{
Name: proto.String(string(method.Name())),
InputType: fullNameOf(method.Input()),
OutputType: fullNameOf(method.Output()),
Options: proto.Clone(method.Options()).(*descriptorpb.MethodOptions),
}
if method.IsStreamingClient() {
p.ClientStreaming = proto.Bool(true)
}
if method.IsStreamingServer() {
p.ServerStreaming = proto.Bool(true)
}
return p
}
func fullNameOf(d protoreflect.Descriptor) *string {
if d == nil {
return nil
}
if strings.HasPrefix(string(d.FullName()), unknownPrefix) {
return proto.String(string(d.FullName()[len(unknownPrefix):]))
}
return proto.String("." + string(d.FullName()))
}

View File

@ -53,6 +53,7 @@ type (
FindExtensionByName(field FullName) (ExtensionType, error) FindExtensionByName(field FullName) (ExtensionType, error)
FindExtensionByNumber(message FullName, field FieldNumber) (ExtensionType, error) FindExtensionByNumber(message FullName, field FieldNumber) (ExtensionType, error)
} }
Depth int
} }
unmarshalOutput = struct { unmarshalOutput = struct {
pragma.NoUnkeyedLiterals pragma.NoUnkeyedLiterals

View File

@ -8,8 +8,7 @@
// defined in proto source files and value interfaces which provide the // defined in proto source files and value interfaces which provide the
// ability to examine and manipulate the contents of messages. // ability to examine and manipulate the contents of messages.
// //
// // # Protocol Buffer Descriptors
// Protocol Buffer Descriptors
// //
// Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor) // Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor)
// are immutable objects that represent protobuf type information. // are immutable objects that represent protobuf type information.
@ -26,8 +25,7 @@
// The "google.golang.org/protobuf/reflect/protodesc" package converts between // The "google.golang.org/protobuf/reflect/protodesc" package converts between
// google.protobuf.DescriptorProto messages and protobuf descriptors. // google.protobuf.DescriptorProto messages and protobuf descriptors.
// //
// // # Go Type Descriptors
// Go Type Descriptors
// //
// A type descriptor (e.g., EnumType or MessageType) is a constructor for // A type descriptor (e.g., EnumType or MessageType) is a constructor for
// a concrete Go type that represents the associated protobuf descriptor. // a concrete Go type that represents the associated protobuf descriptor.
@ -41,8 +39,7 @@
// The "google.golang.org/protobuf/types/dynamicpb" package can be used to // The "google.golang.org/protobuf/types/dynamicpb" package can be used to
// create Go type descriptors from protobuf descriptors. // create Go type descriptors from protobuf descriptors.
// //
// // # Value Interfaces
// Value Interfaces
// //
// The Enum and Message interfaces provide a reflective view over an // The Enum and Message interfaces provide a reflective view over an
// enum or message instance. For enums, it provides the ability to retrieve // enum or message instance. For enums, it provides the ability to retrieve
@ -55,13 +52,11 @@
// The "github.com/golang/protobuf/proto".MessageReflect function can be used // The "github.com/golang/protobuf/proto".MessageReflect function can be used
// to obtain a reflective view on older messages. // to obtain a reflective view on older messages.
// //
// // # Relationships
// Relationships
// //
// The following diagrams demonstrate the relationships between // The following diagrams demonstrate the relationships between
// various types declared in this package. // various types declared in this package.
// //
//
// ┌───────────────────────────────────┐ // ┌───────────────────────────────────┐
// V │ // V │
// ┌────────────── New(n) ─────────────┐ │ // ┌────────────── New(n) ─────────────┐ │
@ -83,7 +78,6 @@
// //
// • An Enum is a concrete enum instance. Generated enums implement Enum. // • An Enum is a concrete enum instance. Generated enums implement Enum.
// //
//
// ┌──────────────── New() ─────────────────┐ // ┌──────────────── New() ─────────────────┐
// │ │ // │ │
// │ ┌─── Descriptor() ─────┐ │ ┌── Interface() ───┐ // │ ┌─── Descriptor() ─────┐ │ ┌── Interface() ───┐
@ -98,12 +92,22 @@
// //
// • A MessageType describes a concrete Go message type. // • A MessageType describes a concrete Go message type.
// It has a MessageDescriptor and can construct a Message instance. // It has a MessageDescriptor and can construct a Message instance.
// Just as how Go's reflect.Type is a reflective description of a Go type,
// a MessageType is a reflective description of a Go type for a protobuf message.
// //
// • A MessageDescriptor describes an abstract protobuf message type. // • A MessageDescriptor describes an abstract protobuf message type.
// It has no understanding of Go types. In order to construct a MessageType
// from just a MessageDescriptor, you can consider looking up the message type
// in the global registry using protoregistry.GlobalTypes.FindMessageByName
// or constructing a dynamic MessageType using dynamicpb.NewMessageType.
// //
// • A Message is a concrete message instance. Generated messages implement // • A Message is a reflective view over a concrete message instance.
// ProtoMessage, which can convert to/from a Message. // Generated messages implement ProtoMessage, which can convert to a Message.
// // Just as how Go's reflect.Value is a reflective view over a Go value,
// a Message is a reflective view over a concrete protobuf message instance.
// Using Go reflection as an analogy, the ProtoReflect method is similar to
// calling reflect.ValueOf, and the Message.Interface method is similar to
// calling reflect.Value.Interface.
// //
// ┌── TypeDescriptor() ──┐ ┌───── Descriptor() ─────┐ // ┌── TypeDescriptor() ──┐ ┌───── Descriptor() ─────┐
// │ V │ V // │ V │ V

View File

@ -4,6 +4,10 @@
package protoreflect package protoreflect
import (
"strconv"
)
// SourceLocations is a list of source locations. // SourceLocations is a list of source locations.
type SourceLocations interface { type SourceLocations interface {
// Len reports the number of source locations in the proto file. // Len reports the number of source locations in the proto file.
@ -11,9 +15,20 @@ type SourceLocations interface {
// Get returns the ith SourceLocation. It panics if out of bounds. // Get returns the ith SourceLocation. It panics if out of bounds.
Get(int) SourceLocation Get(int) SourceLocation
doNotImplement // ByPath returns the SourceLocation for the given path,
// returning the first location if multiple exist for the same path.
// If multiple locations exist for the same path,
// then SourceLocation.Next index can be used to identify the
// index of the next SourceLocation.
// If no location exists for this path, it returns the zero value.
ByPath(path SourcePath) SourceLocation
// TODO: Add ByPath and ByDescriptor helper methods. // ByDescriptor returns the SourceLocation for the given descriptor,
// returning the first location if multiple exist for the same path.
// If no location exists for this descriptor, it returns the zero value.
ByDescriptor(desc Descriptor) SourceLocation
doNotImplement
} }
// SourceLocation describes a source location and // SourceLocation describes a source location and
@ -39,6 +54,10 @@ type SourceLocation struct {
LeadingComments string LeadingComments string
// TrailingComments is the trailing attached comment for the declaration. // TrailingComments is the trailing attached comment for the declaration.
TrailingComments string TrailingComments string
// Next is an index into SourceLocations for the next source location that
// has the same Path. It is zero if there is no next location.
Next int
} }
// SourcePath identifies part of a file descriptor for a source location. // SourcePath identifies part of a file descriptor for a source location.
@ -48,5 +67,63 @@ type SourceLocation struct {
// See google.protobuf.SourceCodeInfo.Location.path. // See google.protobuf.SourceCodeInfo.Location.path.
type SourcePath []int32 type SourcePath []int32
// TODO: Add SourcePath.String method to pretty-print the path. For example: // Equal reports whether p1 equals p2.
// ".message_type[6].nested_type[15].field[3]" func (p1 SourcePath) Equal(p2 SourcePath) bool {
if len(p1) != len(p2) {
return false
}
for i := range p1 {
if p1[i] != p2[i] {
return false
}
}
return true
}
// String formats the path in a humanly readable manner.
// The output is guaranteed to be deterministic,
// making it suitable for use as a key into a Go map.
// It is not guaranteed to be stable as the exact output could change
// in a future version of this module.
//
// Example output:
//
// .message_type[6].nested_type[15].field[3]
func (p SourcePath) String() string {
b := p.appendFileDescriptorProto(nil)
for _, i := range p {
b = append(b, '.')
b = strconv.AppendInt(b, int64(i), 10)
}
return string(b)
}
type appendFunc func(*SourcePath, []byte) []byte
func (p *SourcePath) appendSingularField(b []byte, name string, f appendFunc) []byte {
if len(*p) == 0 {
return b
}
b = append(b, '.')
b = append(b, name...)
*p = (*p)[1:]
if f != nil {
b = f(p, b)
}
return b
}
func (p *SourcePath) appendRepeatedField(b []byte, name string, f appendFunc) []byte {
b = p.appendSingularField(b, name, nil)
if len(*p) == 0 || (*p)[0] < 0 {
return b
}
b = append(b, '[')
b = strconv.AppendUint(b, uint64((*p)[0]), 10)
b = append(b, ']')
*p = (*p)[1:]
if f != nil {
b = f(p, b)
}
return b
}

View File

@ -0,0 +1,461 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by generate-protos. DO NOT EDIT.
package protoreflect
func (p *SourcePath) appendFileDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendSingularField(b, "package", nil)
case 3:
b = p.appendRepeatedField(b, "dependency", nil)
case 10:
b = p.appendRepeatedField(b, "public_dependency", nil)
case 11:
b = p.appendRepeatedField(b, "weak_dependency", nil)
case 4:
b = p.appendRepeatedField(b, "message_type", (*SourcePath).appendDescriptorProto)
case 5:
b = p.appendRepeatedField(b, "enum_type", (*SourcePath).appendEnumDescriptorProto)
case 6:
b = p.appendRepeatedField(b, "service", (*SourcePath).appendServiceDescriptorProto)
case 7:
b = p.appendRepeatedField(b, "extension", (*SourcePath).appendFieldDescriptorProto)
case 8:
b = p.appendSingularField(b, "options", (*SourcePath).appendFileOptions)
case 9:
b = p.appendSingularField(b, "source_code_info", (*SourcePath).appendSourceCodeInfo)
case 12:
b = p.appendSingularField(b, "syntax", nil)
}
return b
}
func (p *SourcePath) appendDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendRepeatedField(b, "field", (*SourcePath).appendFieldDescriptorProto)
case 6:
b = p.appendRepeatedField(b, "extension", (*SourcePath).appendFieldDescriptorProto)
case 3:
b = p.appendRepeatedField(b, "nested_type", (*SourcePath).appendDescriptorProto)
case 4:
b = p.appendRepeatedField(b, "enum_type", (*SourcePath).appendEnumDescriptorProto)
case 5:
b = p.appendRepeatedField(b, "extension_range", (*SourcePath).appendDescriptorProto_ExtensionRange)
case 8:
b = p.appendRepeatedField(b, "oneof_decl", (*SourcePath).appendOneofDescriptorProto)
case 7:
b = p.appendSingularField(b, "options", (*SourcePath).appendMessageOptions)
case 9:
b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendDescriptorProto_ReservedRange)
case 10:
b = p.appendRepeatedField(b, "reserved_name", nil)
}
return b
}
func (p *SourcePath) appendEnumDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendRepeatedField(b, "value", (*SourcePath).appendEnumValueDescriptorProto)
case 3:
b = p.appendSingularField(b, "options", (*SourcePath).appendEnumOptions)
case 4:
b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendEnumDescriptorProto_EnumReservedRange)
case 5:
b = p.appendRepeatedField(b, "reserved_name", nil)
}
return b
}
func (p *SourcePath) appendServiceDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendRepeatedField(b, "method", (*SourcePath).appendMethodDescriptorProto)
case 3:
b = p.appendSingularField(b, "options", (*SourcePath).appendServiceOptions)
}
return b
}
func (p *SourcePath) appendFieldDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 3:
b = p.appendSingularField(b, "number", nil)
case 4:
b = p.appendSingularField(b, "label", nil)
case 5:
b = p.appendSingularField(b, "type", nil)
case 6:
b = p.appendSingularField(b, "type_name", nil)
case 2:
b = p.appendSingularField(b, "extendee", nil)
case 7:
b = p.appendSingularField(b, "default_value", nil)
case 9:
b = p.appendSingularField(b, "oneof_index", nil)
case 10:
b = p.appendSingularField(b, "json_name", nil)
case 8:
b = p.appendSingularField(b, "options", (*SourcePath).appendFieldOptions)
case 17:
b = p.appendSingularField(b, "proto3_optional", nil)
}
return b
}
func (p *SourcePath) appendFileOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "java_package", nil)
case 8:
b = p.appendSingularField(b, "java_outer_classname", nil)
case 10:
b = p.appendSingularField(b, "java_multiple_files", nil)
case 20:
b = p.appendSingularField(b, "java_generate_equals_and_hash", nil)
case 27:
b = p.appendSingularField(b, "java_string_check_utf8", nil)
case 9:
b = p.appendSingularField(b, "optimize_for", nil)
case 11:
b = p.appendSingularField(b, "go_package", nil)
case 16:
b = p.appendSingularField(b, "cc_generic_services", nil)
case 17:
b = p.appendSingularField(b, "java_generic_services", nil)
case 18:
b = p.appendSingularField(b, "py_generic_services", nil)
case 42:
b = p.appendSingularField(b, "php_generic_services", nil)
case 23:
b = p.appendSingularField(b, "deprecated", nil)
case 31:
b = p.appendSingularField(b, "cc_enable_arenas", nil)
case 36:
b = p.appendSingularField(b, "objc_class_prefix", nil)
case 37:
b = p.appendSingularField(b, "csharp_namespace", nil)
case 39:
b = p.appendSingularField(b, "swift_prefix", nil)
case 40:
b = p.appendSingularField(b, "php_class_prefix", nil)
case 41:
b = p.appendSingularField(b, "php_namespace", nil)
case 44:
b = p.appendSingularField(b, "php_metadata_namespace", nil)
case 45:
b = p.appendSingularField(b, "ruby_package", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendSourceCodeInfo(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendRepeatedField(b, "location", (*SourcePath).appendSourceCodeInfo_Location)
}
return b
}
func (p *SourcePath) appendDescriptorProto_ExtensionRange(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "start", nil)
case 2:
b = p.appendSingularField(b, "end", nil)
case 3:
b = p.appendSingularField(b, "options", (*SourcePath).appendExtensionRangeOptions)
}
return b
}
func (p *SourcePath) appendOneofDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendSingularField(b, "options", (*SourcePath).appendOneofOptions)
}
return b
}
func (p *SourcePath) appendMessageOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "message_set_wire_format", nil)
case 2:
b = p.appendSingularField(b, "no_standard_descriptor_accessor", nil)
case 3:
b = p.appendSingularField(b, "deprecated", nil)
case 7:
b = p.appendSingularField(b, "map_entry", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendDescriptorProto_ReservedRange(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "start", nil)
case 2:
b = p.appendSingularField(b, "end", nil)
}
return b
}
func (p *SourcePath) appendEnumValueDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendSingularField(b, "number", nil)
case 3:
b = p.appendSingularField(b, "options", (*SourcePath).appendEnumValueOptions)
}
return b
}
func (p *SourcePath) appendEnumOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 2:
b = p.appendSingularField(b, "allow_alias", nil)
case 3:
b = p.appendSingularField(b, "deprecated", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendEnumDescriptorProto_EnumReservedRange(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "start", nil)
case 2:
b = p.appendSingularField(b, "end", nil)
}
return b
}
func (p *SourcePath) appendMethodDescriptorProto(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name", nil)
case 2:
b = p.appendSingularField(b, "input_type", nil)
case 3:
b = p.appendSingularField(b, "output_type", nil)
case 4:
b = p.appendSingularField(b, "options", (*SourcePath).appendMethodOptions)
case 5:
b = p.appendSingularField(b, "client_streaming", nil)
case 6:
b = p.appendSingularField(b, "server_streaming", nil)
}
return b
}
func (p *SourcePath) appendServiceOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 33:
b = p.appendSingularField(b, "deprecated", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendFieldOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "ctype", nil)
case 2:
b = p.appendSingularField(b, "packed", nil)
case 6:
b = p.appendSingularField(b, "jstype", nil)
case 5:
b = p.appendSingularField(b, "lazy", nil)
case 3:
b = p.appendSingularField(b, "deprecated", nil)
case 10:
b = p.appendSingularField(b, "weak", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendUninterpretedOption(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 2:
b = p.appendRepeatedField(b, "name", (*SourcePath).appendUninterpretedOption_NamePart)
case 3:
b = p.appendSingularField(b, "identifier_value", nil)
case 4:
b = p.appendSingularField(b, "positive_int_value", nil)
case 5:
b = p.appendSingularField(b, "negative_int_value", nil)
case 6:
b = p.appendSingularField(b, "double_value", nil)
case 7:
b = p.appendSingularField(b, "string_value", nil)
case 8:
b = p.appendSingularField(b, "aggregate_value", nil)
}
return b
}
func (p *SourcePath) appendSourceCodeInfo_Location(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendRepeatedField(b, "path", nil)
case 2:
b = p.appendRepeatedField(b, "span", nil)
case 3:
b = p.appendSingularField(b, "leading_comments", nil)
case 4:
b = p.appendSingularField(b, "trailing_comments", nil)
case 6:
b = p.appendRepeatedField(b, "leading_detached_comments", nil)
}
return b
}
func (p *SourcePath) appendExtensionRangeOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendOneofOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendEnumValueOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "deprecated", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendMethodOptions(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 33:
b = p.appendSingularField(b, "deprecated", nil)
case 34:
b = p.appendSingularField(b, "idempotency_level", nil)
case 999:
b = p.appendRepeatedField(b, "uninterpreted_option", (*SourcePath).appendUninterpretedOption)
}
return b
}
func (p *SourcePath) appendUninterpretedOption_NamePart(b []byte) []byte {
if len(*p) == 0 {
return b
}
switch (*p)[0] {
case 1:
b = p.appendSingularField(b, "name_part", nil)
case 2:
b = p.appendSingularField(b, "is_extension", nil)
}
return b
}

View File

@ -232,11 +232,15 @@ type MessageDescriptor interface {
type isMessageDescriptor interface{ ProtoType(MessageDescriptor) } type isMessageDescriptor interface{ ProtoType(MessageDescriptor) }
// MessageType encapsulates a MessageDescriptor with a concrete Go implementation. // MessageType encapsulates a MessageDescriptor with a concrete Go implementation.
// It is recommended that implementations of this interface also implement the
// MessageFieldTypes interface.
type MessageType interface { type MessageType interface {
// New returns a newly allocated empty message. // New returns a newly allocated empty message.
// It may return nil for synthetic messages representing a map entry.
New() Message New() Message
// Zero returns an empty, read-only message. // Zero returns an empty, read-only message.
// It may return nil for synthetic messages representing a map entry.
Zero() Message Zero() Message
// Descriptor returns the message descriptor. // Descriptor returns the message descriptor.
@ -245,6 +249,26 @@ type MessageType interface {
Descriptor() MessageDescriptor Descriptor() MessageDescriptor
} }
// MessageFieldTypes extends a MessageType by providing type information
// regarding enums and messages referenced by the message fields.
type MessageFieldTypes interface {
MessageType
// Enum returns the EnumType for the ith field in Descriptor.Fields.
// It returns nil if the ith field is not an enum kind.
// It panics if out of bounds.
//
// Invariant: mt.Enum(i).Descriptor() == mt.Descriptor().Fields(i).Enum()
Enum(i int) EnumType
// Message returns the MessageType for the ith field in Descriptor.Fields.
// It returns nil if the ith field is not a message or group kind.
// It panics if out of bounds.
//
// Invariant: mt.Message(i).Descriptor() == mt.Descriptor().Fields(i).Message()
Message(i int) MessageType
}
// MessageDescriptors is a list of message declarations. // MessageDescriptors is a list of message declarations.
type MessageDescriptors interface { type MessageDescriptors interface {
// Len reports the number of messages. // Len reports the number of messages.
@ -279,8 +303,15 @@ type FieldDescriptor interface {
// JSONName reports the name used for JSON serialization. // JSONName reports the name used for JSON serialization.
// It is usually the camel-cased form of the field name. // It is usually the camel-cased form of the field name.
// Extension fields are represented by the full name surrounded by brackets.
JSONName() string JSONName() string
// TextName reports the name used for text serialization.
// It is usually the name of the field, except that groups use the name
// of the inlined message, and extension fields are represented by the
// full name surrounded by brackets.
TextName() string
// HasPresence reports whether the field distinguishes between unpopulated // HasPresence reports whether the field distinguishes between unpopulated
// and default values. // and default values.
HasPresence() bool HasPresence() bool
@ -371,6 +402,9 @@ type FieldDescriptors interface {
// ByJSONName returns the FieldDescriptor for a field with s as the JSON name. // ByJSONName returns the FieldDescriptor for a field with s as the JSON name.
// It returns nil if not found. // It returns nil if not found.
ByJSONName(s string) FieldDescriptor ByJSONName(s string) FieldDescriptor
// ByTextName returns the FieldDescriptor for a field with s as the text name.
// It returns nil if not found.
ByTextName(s string) FieldDescriptor
// ByNumber returns the FieldDescriptor for a field numbered n. // ByNumber returns the FieldDescriptor for a field numbered n.
// It returns nil if not found. // It returns nil if not found.
ByNumber(n FieldNumber) FieldDescriptor ByNumber(n FieldNumber) FieldDescriptor
@ -446,6 +480,7 @@ type ExtensionDescriptors interface {
// relative to the parent that it is declared within. // relative to the parent that it is declared within.
// //
// For example: // For example:
//
// syntax = "proto2"; // syntax = "proto2";
// package example; // package example;
// message FooMessage { // message FooMessage {

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build purego || appengine
// +build purego appengine // +build purego appengine
package protoreflect package protoreflect

View File

@ -41,6 +41,32 @@ import (
// Converting to/from a Value and a concrete Go value panics on type mismatch. // Converting to/from a Value and a concrete Go value panics on type mismatch.
// For example, ValueOf("hello").Int() panics because this attempts to // For example, ValueOf("hello").Int() panics because this attempts to
// retrieve an int64 from a string. // retrieve an int64 from a string.
//
// List, Map, and Message Values are called "composite" values.
//
// A composite Value may alias (reference) memory at some location,
// such that changes to the Value updates the that location.
// A composite value acquired with a Mutable method, such as Message.Mutable,
// always references the source object.
//
// For example:
//
// // Append a 0 to a "repeated int32" field.
// // Since the Value returned by Mutable is guaranteed to alias
// // the source message, modifying the Value modifies the message.
// message.Mutable(fieldDesc).(List).Append(protoreflect.ValueOfInt32(0))
//
// // Assign [0] to a "repeated int32" field by creating a new Value,
// // modifying it, and assigning it.
// list := message.NewField(fieldDesc).(List)
// list.Append(protoreflect.ValueOfInt32(0))
// message.Set(fieldDesc, list)
// // ERROR: Since it is not defined whether Set aliases the source,
// // appending to the List here may or may not modify the message.
// list.Append(protoreflect.ValueOfInt32(0))
//
// Some operations, such as Message.Get, may return an "empty, read-only"
// composite Value. Modifying an empty, read-only value panics.
type Value value type Value value
// The protoreflect API uses a custom Value union type instead of interface{} // The protoreflect API uses a custom Value union type instead of interface{}
@ -367,6 +393,7 @@ func (v Value) MapKey() MapKey {
// ╚═════════╧═════════════════════════════════════╝ // ╚═════════╧═════════════════════════════════════╝
// //
// A MapKey is constructed and accessed through a Value: // A MapKey is constructed and accessed through a Value:
//
// k := ValueOf("hash").MapKey() // convert string to MapKey // k := ValueOf("hash").MapKey() // convert string to MapKey
// s := k.String() // convert MapKey to string // s := k.String() // convert MapKey to string
// //

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !purego && !appengine
// +build !purego,!appengine // +build !purego,!appengine
package protoreflect package protoreflect

View File

@ -17,24 +17,51 @@ package protoregistry
import ( import (
"fmt" "fmt"
"log" "os"
"strings" "strings"
"sync" "sync"
"google.golang.org/protobuf/internal/encoding/messageset"
"google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/errors"
"google.golang.org/protobuf/internal/flags"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
) )
// conflictPolicy configures the policy for handling registration conflicts.
//
// It can be over-written at compile time with a linker-initialized variable:
//
// go build -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
//
// It can be over-written at program execution with an environment variable:
//
// GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main
//
// Neither of the above are covered by the compatibility promise and
// may be removed in a future release of this module.
var conflictPolicy = "panic" // "panic" | "warn" | "ignore"
// ignoreConflict reports whether to ignore a registration conflict // ignoreConflict reports whether to ignore a registration conflict
// given the descriptor being registered and the error. // given the descriptor being registered and the error.
// It is a variable so that the behavior is easily overridden in another file. // It is a variable so that the behavior is easily overridden in another file.
var ignoreConflict = func(d protoreflect.Descriptor, err error) bool { var ignoreConflict = func(d protoreflect.Descriptor, err error) bool {
log.Printf(""+ const env = "GOLANG_PROTOBUF_REGISTRATION_CONFLICT"
"WARNING: %v\n"+ const faq = "https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict"
"A future release will panic on registration conflicts. See:\n"+ policy := conflictPolicy
"https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict\n"+ if v := os.Getenv(env); v != "" {
"\n", err) policy = v
}
switch policy {
case "panic":
panic(fmt.Sprintf("%v\nSee %v\n", err, faq))
case "warn":
fmt.Fprintf(os.Stderr, "WARNING: %v\nSee %v\n\n", err, faq)
return true return true
case "ignore":
return true
default:
panic("invalid " + env + " value: " + os.Getenv(env))
}
} }
var globalMutex sync.RWMutex var globalMutex sync.RWMutex
@ -69,7 +96,8 @@ type Files struct {
// Note that enum values are in the top-level since that are in the same // Note that enum values are in the top-level since that are in the same
// scope as the parent enum. // scope as the parent enum.
descsByName map[protoreflect.FullName]interface{} descsByName map[protoreflect.FullName]interface{}
filesByPath map[string]protoreflect.FileDescriptor filesByPath map[string][]protoreflect.FileDescriptor
numFiles int
} }
type packageDescriptor struct { type packageDescriptor struct {
@ -92,49 +120,17 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
r.descsByName = map[protoreflect.FullName]interface{}{ r.descsByName = map[protoreflect.FullName]interface{}{
"": &packageDescriptor{}, "": &packageDescriptor{},
} }
r.filesByPath = make(map[string]protoreflect.FileDescriptor) r.filesByPath = make(map[string][]protoreflect.FileDescriptor)
} }
path := file.Path() path := file.Path()
if prev := r.filesByPath[path]; prev != nil { if prev := r.filesByPath[path]; len(prev) > 0 {
// TODO: Remove this after some soak-in period after moving these types. r.checkGenProtoConflict(path)
var prevPath string
const prevModule = "google.golang.org/genproto"
const prevVersion = "cb27e3aa (May 26th, 2020)"
switch path {
case "google/protobuf/field_mask.proto":
prevPath = prevModule + "/protobuf/field_mask"
case "google/protobuf/api.proto":
prevPath = prevModule + "/protobuf/api"
case "google/protobuf/type.proto":
prevPath = prevModule + "/protobuf/ptype"
case "google/protobuf/source_context.proto":
prevPath = prevModule + "/protobuf/source_context"
}
if r == GlobalFiles && prevPath != "" {
pkgName := strings.TrimSuffix(strings.TrimPrefix(path, "google/protobuf/"), ".proto")
pkgName = strings.Replace(pkgName, "_", "", -1) + "pb"
currPath := "google.golang.org/protobuf/types/known/" + pkgName
panic(fmt.Sprintf(""+
"duplicate registration of %q\n"+
"\n"+
"The generated definition for this file has moved:\n"+
"\tfrom: %q\n"+
"\tto: %q\n"+
"A dependency on the %q module must\n"+
"be at version %v or higher.\n"+
"\n"+
"Upgrade the dependency by running:\n"+
"\tgo get -u %v\n",
path, prevPath, currPath, prevModule, prevVersion, prevPath))
}
err := errors.New("file %q is already registered", file.Path()) err := errors.New("file %q is already registered", file.Path())
err = amendErrorWithCaller(err, prev, file) err = amendErrorWithCaller(err, prev[0], file)
if r == GlobalFiles && ignoreConflict(file, err) { if !(r == GlobalFiles && ignoreConflict(file, err)) {
err = nil
}
return err return err
} }
}
for name := file.Package(); name != ""; name = name.Parent() { for name := file.Package(); name != ""; name = name.Parent() {
switch prev := r.descsByName[name]; prev.(type) { switch prev := r.descsByName[name]; prev.(type) {
@ -174,10 +170,52 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) { rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
r.descsByName[d.FullName()] = d r.descsByName[d.FullName()] = d
}) })
r.filesByPath[path] = file r.filesByPath[path] = append(r.filesByPath[path], file)
r.numFiles++
return nil return nil
} }
// Several well-known types were hosted in the google.golang.org/genproto module
// but were later moved to this module. To avoid a weak dependency on the
// genproto module (and its relatively large set of transitive dependencies),
// we rely on a registration conflict to determine whether the genproto version
// is too old (i.e., does not contain aliases to the new type declarations).
func (r *Files) checkGenProtoConflict(path string) {
if r != GlobalFiles {
return
}
var prevPath string
const prevModule = "google.golang.org/genproto"
const prevVersion = "cb27e3aa (May 26th, 2020)"
switch path {
case "google/protobuf/field_mask.proto":
prevPath = prevModule + "/protobuf/field_mask"
case "google/protobuf/api.proto":
prevPath = prevModule + "/protobuf/api"
case "google/protobuf/type.proto":
prevPath = prevModule + "/protobuf/ptype"
case "google/protobuf/source_context.proto":
prevPath = prevModule + "/protobuf/source_context"
default:
return
}
pkgName := strings.TrimSuffix(strings.TrimPrefix(path, "google/protobuf/"), ".proto")
pkgName = strings.Replace(pkgName, "_", "", -1) + "pb" // e.g., "field_mask" => "fieldmaskpb"
currPath := "google.golang.org/protobuf/types/known/" + pkgName
panic(fmt.Sprintf(""+
"duplicate registration of %q\n"+
"\n"+
"The generated definition for this file has moved:\n"+
"\tfrom: %q\n"+
"\tto: %q\n"+
"A dependency on the %q module must\n"+
"be at version %v or higher.\n"+
"\n"+
"Upgrade the dependency by running:\n"+
"\tgo get -u %v\n",
path, prevPath, currPath, prevModule, prevVersion, prevPath))
}
// FindDescriptorByName looks up a descriptor by the full name. // FindDescriptorByName looks up a descriptor by the full name.
// //
// This returns (nil, NotFound) if not found. // This returns (nil, NotFound) if not found.
@ -273,6 +311,7 @@ func (s *nameSuffix) Pop() (name protoreflect.Name) {
// FindFileByPath looks up a file by the path. // FindFileByPath looks up a file by the path.
// //
// This returns (nil, NotFound) if not found. // This returns (nil, NotFound) if not found.
// This returns an error if multiple files have the same path.
func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) { func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
if r == nil { if r == nil {
return nil, NotFound return nil, NotFound
@ -281,13 +320,19 @@ func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error)
globalMutex.RLock() globalMutex.RLock()
defer globalMutex.RUnlock() defer globalMutex.RUnlock()
} }
if fd, ok := r.filesByPath[path]; ok { fds := r.filesByPath[path]
return fd, nil switch len(fds) {
} case 0:
return nil, NotFound return nil, NotFound
case 1:
return fds[0], nil
default:
return nil, errors.New("multiple files named %q", path)
}
} }
// NumFiles reports the number of registered files. // NumFiles reports the number of registered files,
// including duplicate files with the same name.
func (r *Files) NumFiles() int { func (r *Files) NumFiles() int {
if r == nil { if r == nil {
return 0 return 0
@ -296,10 +341,11 @@ func (r *Files) NumFiles() int {
globalMutex.RLock() globalMutex.RLock()
defer globalMutex.RUnlock() defer globalMutex.RUnlock()
} }
return len(r.filesByPath) return r.numFiles
} }
// RangeFiles iterates over all registered files while f returns true. // RangeFiles iterates over all registered files while f returns true.
// If multiple files have the same name, RangeFiles iterates over all of them.
// The iteration order is undefined. // The iteration order is undefined.
func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) { func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
if r == nil { if r == nil {
@ -309,11 +355,13 @@ func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
globalMutex.RLock() globalMutex.RLock()
defer globalMutex.RUnlock() defer globalMutex.RUnlock()
} }
for _, file := range r.filesByPath { for _, files := range r.filesByPath {
for _, file := range files {
if !f(file) { if !f(file) {
return return
} }
} }
}
} }
// NumFilesByPackage reports the number of registered files in a proto package. // NumFilesByPackage reports the number of registered files in a proto package.
@ -560,13 +608,25 @@ func (r *Types) FindEnumByName(enum protoreflect.FullName) (protoreflect.EnumTyp
return nil, NotFound return nil, NotFound
} }
// FindMessageByName looks up a message by its full name. // FindMessageByName looks up a message by its full name,
// E.g., "google.protobuf.Any" // e.g. "google.protobuf.Any".
// //
// This return (nil, NotFound) if not found. // This returns (nil, NotFound) if not found.
func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
// The full name by itself is a valid URL. if r == nil {
return r.FindMessageByURL(string(message)) return nil, NotFound
}
if r == GlobalTypes {
globalMutex.RLock()
defer globalMutex.RUnlock()
}
if v := r.typesByName[message]; v != nil {
if mt, _ := v.(protoreflect.MessageType); mt != nil {
return mt, nil
}
return nil, errors.New("found wrong type: got %v, want message", typeName(v))
}
return nil, NotFound
} }
// FindMessageByURL looks up a message by a URL identifier. // FindMessageByURL looks up a message by a URL identifier.
@ -574,6 +634,8 @@ func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.M
// //
// This returns (nil, NotFound) if not found. // This returns (nil, NotFound) if not found.
func (r *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) { func (r *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) {
// This function is similar to FindMessageByName but
// truncates anything before and including '/' in the URL.
if r == nil { if r == nil {
return nil, NotFound return nil, NotFound
} }
@ -613,6 +675,26 @@ func (r *Types) FindExtensionByName(field protoreflect.FullName) (protoreflect.E
if xt, _ := v.(protoreflect.ExtensionType); xt != nil { if xt, _ := v.(protoreflect.ExtensionType); xt != nil {
return xt, nil return xt, nil
} }
// MessageSet extensions are special in that the name of the extension
// is the name of the message type used to extend the MessageSet.
// This naming scheme is used by text and JSON serialization.
//
// This feature is protected by the ProtoLegacy flag since MessageSets
// are a proto1 feature that is long deprecated.
if flags.ProtoLegacy {
if _, ok := v.(protoreflect.MessageType); ok {
field := field.Append(messageset.ExtensionName)
if v := r.typesByName[field]; v != nil {
if xt, _ := v.(protoreflect.ExtensionType); xt != nil {
if messageset.IsMessageSetExtension(xt.TypeDescriptor()) {
return xt, nil
}
}
}
}
}
return nil, errors.New("found wrong type: got %v, want extension", typeName(v)) return nil, errors.New("found wrong type: got %v, want extension", typeName(v))
} }
return nil, NotFound return nil, NotFound

Some files were not shown because too many files have changed in this diff Show More