...

Source file src/google.golang.org/protobuf/internal/filedesc/editions.go

Documentation: google.golang.org/protobuf/internal/filedesc

     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  
     5  package filedesc
     6  
     7  import (
     8  	"fmt"
     9  
    10  	"google.golang.org/protobuf/encoding/protowire"
    11  	"google.golang.org/protobuf/internal/editiondefaults"
    12  	"google.golang.org/protobuf/internal/genid"
    13  	"google.golang.org/protobuf/reflect/protoreflect"
    14  )
    15  
    16  var defaultsCache = make(map[Edition]EditionFeatures)
    17  var defaultsKeys = []Edition{}
    18  
    19  func init() {
    20  	unmarshalEditionDefaults(editiondefaults.Defaults)
    21  	SurrogateProto2.L1.EditionFeatures = getFeaturesFor(EditionProto2)
    22  	SurrogateProto3.L1.EditionFeatures = getFeaturesFor(EditionProto3)
    23  	SurrogateEdition2023.L1.EditionFeatures = getFeaturesFor(Edition2023)
    24  }
    25  
    26  func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
    27  	for len(b) > 0 {
    28  		num, _, n := protowire.ConsumeTag(b)
    29  		b = b[n:]
    30  		switch num {
    31  		case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
    32  			v, m := protowire.ConsumeVarint(b)
    33  			b = b[m:]
    34  			parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v)
    35  		default:
    36  			panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num))
    37  		}
    38  	}
    39  	return parent
    40  }
    41  
    42  func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
    43  	for len(b) > 0 {
    44  		num, typ, n := protowire.ConsumeTag(b)
    45  		b = b[n:]
    46  		switch typ {
    47  		case protowire.VarintType:
    48  			v, m := protowire.ConsumeVarint(b)
    49  			b = b[m:]
    50  			switch num {
    51  			case genid.FeatureSet_FieldPresence_field_number:
    52  				parent.IsFieldPresence = v == genid.FeatureSet_EXPLICIT_enum_value || v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
    53  				parent.IsLegacyRequired = v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
    54  			case genid.FeatureSet_EnumType_field_number:
    55  				parent.IsOpenEnum = v == genid.FeatureSet_OPEN_enum_value
    56  			case genid.FeatureSet_RepeatedFieldEncoding_field_number:
    57  				parent.IsPacked = v == genid.FeatureSet_PACKED_enum_value
    58  			case genid.FeatureSet_Utf8Validation_field_number:
    59  				parent.IsUTF8Validated = v == genid.FeatureSet_VERIFY_enum_value
    60  			case genid.FeatureSet_MessageEncoding_field_number:
    61  				parent.IsDelimitedEncoded = v == genid.FeatureSet_DELIMITED_enum_value
    62  			case genid.FeatureSet_JsonFormat_field_number:
    63  				parent.IsJSONCompliant = v == genid.FeatureSet_ALLOW_enum_value
    64  			default:
    65  				panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num))
    66  			}
    67  		case protowire.BytesType:
    68  			v, m := protowire.ConsumeBytes(b)
    69  			b = b[m:]
    70  			switch num {
    71  			case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
    72  				parent = unmarshalGoFeature(v, parent)
    73  			}
    74  		}
    75  	}
    76  
    77  	return parent
    78  }
    79  
    80  func featuresFromParentDesc(parentDesc protoreflect.Descriptor) EditionFeatures {
    81  	var parentFS EditionFeatures
    82  	switch p := parentDesc.(type) {
    83  	case *File:
    84  		parentFS = p.L1.EditionFeatures
    85  	case *Message:
    86  		parentFS = p.L1.EditionFeatures
    87  	default:
    88  		panic(fmt.Sprintf("unknown parent type %T", parentDesc))
    89  	}
    90  	return parentFS
    91  }
    92  
    93  func unmarshalEditionDefault(b []byte) {
    94  	var ed Edition
    95  	var fs EditionFeatures
    96  	for len(b) > 0 {
    97  		num, typ, n := protowire.ConsumeTag(b)
    98  		b = b[n:]
    99  		switch typ {
   100  		case protowire.VarintType:
   101  			v, m := protowire.ConsumeVarint(b)
   102  			b = b[m:]
   103  			switch num {
   104  			case genid.FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_number:
   105  				ed = Edition(v)
   106  			}
   107  		case protowire.BytesType:
   108  			v, m := protowire.ConsumeBytes(b)
   109  			b = b[m:]
   110  			switch num {
   111  			case genid.FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_number:
   112  				fs = unmarshalFeatureSet(v, fs)
   113  			case genid.FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_number:
   114  				fs = unmarshalFeatureSet(v, fs)
   115  			}
   116  		}
   117  	}
   118  	defaultsCache[ed] = fs
   119  	defaultsKeys = append(defaultsKeys, ed)
   120  }
   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  
   144  func getFeaturesFor(ed Edition) EditionFeatures {
   145  	match := EditionUnknown
   146  	for _, key := range defaultsKeys {
   147  		if key > ed {
   148  			break
   149  		}
   150  		match = key
   151  	}
   152  	if match == EditionUnknown {
   153  		panic(fmt.Sprintf("unsupported edition: %v", ed))
   154  	}
   155  	return defaultsCache[match]
   156  }
   157  

View as plain text