editions.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. var defaultsKeys = []Edition{}
  14. func init() {
  15. unmarshalEditionDefaults(editiondefaults.Defaults)
  16. SurrogateProto2.L1.EditionFeatures = getFeaturesFor(EditionProto2)
  17. SurrogateProto3.L1.EditionFeatures = getFeaturesFor(EditionProto3)
  18. SurrogateEdition2023.L1.EditionFeatures = getFeaturesFor(Edition2023)
  19. }
  20. func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
  21. for len(b) > 0 {
  22. num, _, n := protowire.ConsumeTag(b)
  23. b = b[n:]
  24. switch num {
  25. case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
  26. v, m := protowire.ConsumeVarint(b)
  27. b = b[m:]
  28. parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v)
  29. case genid.GoFeatures_ApiLevel_field_number:
  30. v, m := protowire.ConsumeVarint(b)
  31. b = b[m:]
  32. parent.APILevel = int(v)
  33. case genid.GoFeatures_StripEnumPrefix_field_number:
  34. v, m := protowire.ConsumeVarint(b)
  35. b = b[m:]
  36. parent.StripEnumPrefix = int(v)
  37. default:
  38. panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num))
  39. }
  40. }
  41. return parent
  42. }
  43. func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
  44. for len(b) > 0 {
  45. num, typ, n := protowire.ConsumeTag(b)
  46. b = b[n:]
  47. switch typ {
  48. case protowire.VarintType:
  49. v, m := protowire.ConsumeVarint(b)
  50. b = b[m:]
  51. switch num {
  52. case genid.FeatureSet_FieldPresence_field_number:
  53. parent.IsFieldPresence = v == genid.FeatureSet_EXPLICIT_enum_value || v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
  54. parent.IsLegacyRequired = v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
  55. case genid.FeatureSet_EnumType_field_number:
  56. parent.IsOpenEnum = v == genid.FeatureSet_OPEN_enum_value
  57. case genid.FeatureSet_RepeatedFieldEncoding_field_number:
  58. parent.IsPacked = v == genid.FeatureSet_PACKED_enum_value
  59. case genid.FeatureSet_Utf8Validation_field_number:
  60. parent.IsUTF8Validated = v == genid.FeatureSet_VERIFY_enum_value
  61. case genid.FeatureSet_MessageEncoding_field_number:
  62. parent.IsDelimitedEncoded = v == genid.FeatureSet_DELIMITED_enum_value
  63. case genid.FeatureSet_JsonFormat_field_number:
  64. parent.IsJSONCompliant = v == genid.FeatureSet_ALLOW_enum_value
  65. case genid.FeatureSet_EnforceNamingStyle_field_number:
  66. // EnforceNamingStyle is enforced in protoc, languages other than C++
  67. // are not supposed to do anything with this feature.
  68. default:
  69. panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num))
  70. }
  71. case protowire.BytesType:
  72. v, m := protowire.ConsumeBytes(b)
  73. b = b[m:]
  74. switch num {
  75. case genid.FeatureSet_Go_ext_number:
  76. parent = unmarshalGoFeature(v, parent)
  77. }
  78. }
  79. }
  80. return parent
  81. }
  82. func featuresFromParentDesc(parentDesc protoreflect.Descriptor) EditionFeatures {
  83. var parentFS EditionFeatures
  84. switch p := parentDesc.(type) {
  85. case *File:
  86. parentFS = p.L1.EditionFeatures
  87. case *Message:
  88. parentFS = p.L1.EditionFeatures
  89. default:
  90. panic(fmt.Sprintf("unknown parent type %T", parentDesc))
  91. }
  92. return parentFS
  93. }
  94. func unmarshalEditionDefault(b []byte) {
  95. var ed Edition
  96. var fs EditionFeatures
  97. for len(b) > 0 {
  98. num, typ, n := protowire.ConsumeTag(b)
  99. b = b[n:]
  100. switch typ {
  101. case protowire.VarintType:
  102. v, m := protowire.ConsumeVarint(b)
  103. b = b[m:]
  104. switch num {
  105. case genid.FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_number:
  106. ed = Edition(v)
  107. }
  108. case protowire.BytesType:
  109. v, m := protowire.ConsumeBytes(b)
  110. b = b[m:]
  111. switch num {
  112. case genid.FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_number:
  113. fs = unmarshalFeatureSet(v, fs)
  114. case genid.FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_number:
  115. fs = unmarshalFeatureSet(v, fs)
  116. }
  117. }
  118. }
  119. defaultsCache[ed] = fs
  120. defaultsKeys = append(defaultsKeys, ed)
  121. }
  122. func unmarshalEditionDefaults(b []byte) {
  123. for len(b) > 0 {
  124. num, _, n := protowire.ConsumeTag(b)
  125. b = b[n:]
  126. switch num {
  127. case genid.FeatureSetDefaults_Defaults_field_number:
  128. def, m := protowire.ConsumeBytes(b)
  129. b = b[m:]
  130. unmarshalEditionDefault(def)
  131. case genid.FeatureSetDefaults_MinimumEdition_field_number,
  132. genid.FeatureSetDefaults_MaximumEdition_field_number:
  133. // We don't care about the minimum and maximum editions. If the
  134. // edition we are looking for later on is not in the cache we know
  135. // it is outside of the range between minimum and maximum edition.
  136. _, m := protowire.ConsumeVarint(b)
  137. b = b[m:]
  138. default:
  139. panic(fmt.Sprintf("unkown field number %d while unmarshalling EditionDefault", num))
  140. }
  141. }
  142. }
  143. func getFeaturesFor(ed Edition) EditionFeatures {
  144. match := EditionUnknown
  145. for _, key := range defaultsKeys {
  146. if key > ed {
  147. break
  148. }
  149. match = key
  150. }
  151. if match == EditionUnknown {
  152. panic(fmt.Sprintf("unsupported edition: %v", ed))
  153. }
  154. return defaultsCache[match]
  155. }