editions.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2024 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package filedesc
  5. import (
  6. "fmt"
  7. "google.golang.org/protobuf/encoding/protowire"
  8. "google.golang.org/protobuf/internal/editiondefaults"
  9. "google.golang.org/protobuf/internal/genid"
  10. "google.golang.org/protobuf/reflect/protoreflect"
  11. )
  12. var defaultsCache = make(map[Edition]EditionFeatures)
  13. func init() {
  14. unmarshalEditionDefaults(editiondefaults.Defaults)
  15. }
  16. func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
  17. for len(b) > 0 {
  18. num, _, n := protowire.ConsumeTag(b)
  19. b = b[n:]
  20. switch num {
  21. case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
  22. v, m := protowire.ConsumeVarint(b)
  23. b = b[m:]
  24. parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v)
  25. default:
  26. panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num))
  27. }
  28. }
  29. return parent
  30. }
  31. func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
  32. for len(b) > 0 {
  33. num, typ, n := protowire.ConsumeTag(b)
  34. b = b[n:]
  35. switch typ {
  36. case protowire.VarintType:
  37. v, m := protowire.ConsumeVarint(b)
  38. b = b[m:]
  39. switch num {
  40. case genid.FeatureSet_FieldPresence_field_number:
  41. parent.IsFieldPresence = v == genid.FeatureSet_EXPLICIT_enum_value || v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
  42. parent.IsLegacyRequired = v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
  43. case genid.FeatureSet_EnumType_field_number:
  44. parent.IsOpenEnum = v == genid.FeatureSet_OPEN_enum_value
  45. case genid.FeatureSet_RepeatedFieldEncoding_field_number:
  46. parent.IsPacked = v == genid.FeatureSet_PACKED_enum_value
  47. case genid.FeatureSet_Utf8Validation_field_number:
  48. parent.IsUTF8Validated = v == genid.FeatureSet_VERIFY_enum_value
  49. case genid.FeatureSet_MessageEncoding_field_number:
  50. parent.IsDelimitedEncoded = v == genid.FeatureSet_DELIMITED_enum_value
  51. case genid.FeatureSet_JsonFormat_field_number:
  52. parent.IsJSONCompliant = v == genid.FeatureSet_ALLOW_enum_value
  53. default:
  54. panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num))
  55. }
  56. case protowire.BytesType:
  57. v, m := protowire.ConsumeBytes(b)
  58. b = b[m:]
  59. switch num {
  60. case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
  61. parent = unmarshalGoFeature(v, parent)
  62. }
  63. }
  64. }
  65. return parent
  66. }
  67. func featuresFromParentDesc(parentDesc protoreflect.Descriptor) EditionFeatures {
  68. var parentFS EditionFeatures
  69. switch p := parentDesc.(type) {
  70. case *File:
  71. parentFS = p.L1.EditionFeatures
  72. case *Message:
  73. parentFS = p.L1.EditionFeatures
  74. default:
  75. panic(fmt.Sprintf("unknown parent type %T", parentDesc))
  76. }
  77. return parentFS
  78. }
  79. func unmarshalEditionDefault(b []byte) {
  80. var ed Edition
  81. var fs EditionFeatures
  82. for len(b) > 0 {
  83. num, typ, n := protowire.ConsumeTag(b)
  84. b = b[n:]
  85. switch typ {
  86. case protowire.VarintType:
  87. v, m := protowire.ConsumeVarint(b)
  88. b = b[m:]
  89. switch num {
  90. case genid.FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_number:
  91. ed = Edition(v)
  92. }
  93. case protowire.BytesType:
  94. v, m := protowire.ConsumeBytes(b)
  95. b = b[m:]
  96. switch num {
  97. case genid.FeatureSetDefaults_FeatureSetEditionDefault_Features_field_number:
  98. fs = unmarshalFeatureSet(v, fs)
  99. }
  100. }
  101. }
  102. defaultsCache[ed] = fs
  103. }
  104. func unmarshalEditionDefaults(b []byte) {
  105. for len(b) > 0 {
  106. num, _, n := protowire.ConsumeTag(b)
  107. b = b[n:]
  108. switch num {
  109. case genid.FeatureSetDefaults_Defaults_field_number:
  110. def, m := protowire.ConsumeBytes(b)
  111. b = b[m:]
  112. unmarshalEditionDefault(def)
  113. case genid.FeatureSetDefaults_MinimumEdition_field_number,
  114. genid.FeatureSetDefaults_MaximumEdition_field_number:
  115. // We don't care about the minimum and maximum editions. If the
  116. // edition we are looking for later on is not in the cache we know
  117. // it is outside of the range between minimum and maximum edition.
  118. _, m := protowire.ConsumeVarint(b)
  119. b = b[m:]
  120. default:
  121. panic(fmt.Sprintf("unkown field number %d while unmarshalling EditionDefault", num))
  122. }
  123. }
  124. }
  125. func getFeaturesFor(ed Edition) EditionFeatures {
  126. if def, ok := defaultsCache[ed]; ok {
  127. return def
  128. }
  129. panic(fmt.Sprintf("unsupported edition: %v", ed))
  130. }