github.com/jhump/protoreflect@v1.16.0/desc/builder/types.go (about)

     1  package builder
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"google.golang.org/protobuf/types/descriptorpb"
     7  
     8  	"github.com/jhump/protoreflect/desc"
     9  )
    10  
    11  // FieldType represents the type of a field or extension. It can represent a
    12  // message or enum type or any of the scalar types supported by protobufs.
    13  //
    14  // Message and enum types can reference a message or enum builder. A type that
    15  // refers to a built message or enum descriptor is called an "imported" type.
    16  //
    17  // There are numerous factory methods for creating FieldType instances.
    18  type FieldType struct {
    19  	fieldType       descriptorpb.FieldDescriptorProto_Type
    20  	foreignMsgType  *desc.MessageDescriptor
    21  	localMsgType    *MessageBuilder
    22  	foreignEnumType *desc.EnumDescriptor
    23  	localEnumType   *EnumBuilder
    24  }
    25  
    26  // GetType returns the enum value indicating the type of the field. If the type
    27  // is a message (or group) or enum type, GetTypeName provides the name of the
    28  // referenced type.
    29  func (ft *FieldType) GetType() descriptorpb.FieldDescriptorProto_Type {
    30  	return ft.fieldType
    31  }
    32  
    33  // GetTypeName returns the fully-qualified name of the referenced message or
    34  // enum type. It returns an empty string if this type does not represent a
    35  // message or enum type.
    36  func (ft *FieldType) GetTypeName() string {
    37  	if ft.foreignMsgType != nil {
    38  		return ft.foreignMsgType.GetFullyQualifiedName()
    39  	} else if ft.foreignEnumType != nil {
    40  		return ft.foreignEnumType.GetFullyQualifiedName()
    41  	} else if ft.localMsgType != nil {
    42  		return GetFullyQualifiedName(ft.localMsgType)
    43  	} else if ft.localEnumType != nil {
    44  		return GetFullyQualifiedName(ft.localEnumType)
    45  	} else {
    46  		return ""
    47  	}
    48  }
    49  
    50  var scalarTypes = map[descriptorpb.FieldDescriptorProto_Type]*FieldType{
    51  	descriptorpb.FieldDescriptorProto_TYPE_BOOL:     {fieldType: descriptorpb.FieldDescriptorProto_TYPE_BOOL},
    52  	descriptorpb.FieldDescriptorProto_TYPE_INT32:    {fieldType: descriptorpb.FieldDescriptorProto_TYPE_INT32},
    53  	descriptorpb.FieldDescriptorProto_TYPE_INT64:    {fieldType: descriptorpb.FieldDescriptorProto_TYPE_INT64},
    54  	descriptorpb.FieldDescriptorProto_TYPE_SINT32:   {fieldType: descriptorpb.FieldDescriptorProto_TYPE_SINT32},
    55  	descriptorpb.FieldDescriptorProto_TYPE_SINT64:   {fieldType: descriptorpb.FieldDescriptorProto_TYPE_SINT64},
    56  	descriptorpb.FieldDescriptorProto_TYPE_UINT32:   {fieldType: descriptorpb.FieldDescriptorProto_TYPE_UINT32},
    57  	descriptorpb.FieldDescriptorProto_TYPE_UINT64:   {fieldType: descriptorpb.FieldDescriptorProto_TYPE_UINT64},
    58  	descriptorpb.FieldDescriptorProto_TYPE_FIXED32:  {fieldType: descriptorpb.FieldDescriptorProto_TYPE_FIXED32},
    59  	descriptorpb.FieldDescriptorProto_TYPE_FIXED64:  {fieldType: descriptorpb.FieldDescriptorProto_TYPE_FIXED64},
    60  	descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: {fieldType: descriptorpb.FieldDescriptorProto_TYPE_SFIXED32},
    61  	descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: {fieldType: descriptorpb.FieldDescriptorProto_TYPE_SFIXED64},
    62  	descriptorpb.FieldDescriptorProto_TYPE_FLOAT:    {fieldType: descriptorpb.FieldDescriptorProto_TYPE_FLOAT},
    63  	descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:   {fieldType: descriptorpb.FieldDescriptorProto_TYPE_DOUBLE},
    64  	descriptorpb.FieldDescriptorProto_TYPE_STRING:   {fieldType: descriptorpb.FieldDescriptorProto_TYPE_STRING},
    65  	descriptorpb.FieldDescriptorProto_TYPE_BYTES:    {fieldType: descriptorpb.FieldDescriptorProto_TYPE_BYTES},
    66  }
    67  
    68  // FieldTypeScalar returns a FieldType for the given scalar type. If the given
    69  // type is not scalar (e.g. it is a message, group, or enum) than this function
    70  // will panic.
    71  func FieldTypeScalar(t descriptorpb.FieldDescriptorProto_Type) *FieldType {
    72  	if ft, ok := scalarTypes[t]; ok {
    73  		return ft
    74  	}
    75  	panic(fmt.Sprintf("field %v is not scalar", t))
    76  }
    77  
    78  // FieldTypeInt32 returns a FieldType for the int32 scalar type.
    79  func FieldTypeInt32() *FieldType {
    80  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_INT32)
    81  }
    82  
    83  // FieldTypeUInt32 returns a FieldType for the uint32 scalar type.
    84  func FieldTypeUInt32() *FieldType {
    85  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_UINT32)
    86  }
    87  
    88  // FieldTypeSInt32 returns a FieldType for the sint32 scalar type.
    89  func FieldTypeSInt32() *FieldType {
    90  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_SINT32)
    91  }
    92  
    93  // FieldTypeFixed32 returns a FieldType for the fixed32 scalar type.
    94  func FieldTypeFixed32() *FieldType {
    95  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_FIXED32)
    96  }
    97  
    98  // FieldTypeSFixed32 returns a FieldType for the sfixed32 scalar type.
    99  func FieldTypeSFixed32() *FieldType {
   100  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_SFIXED32)
   101  }
   102  
   103  // FieldTypeInt64 returns a FieldType for the int64 scalar type.
   104  func FieldTypeInt64() *FieldType {
   105  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_INT64)
   106  }
   107  
   108  // FieldTypeUInt64 returns a FieldType for the uint64 scalar type.
   109  func FieldTypeUInt64() *FieldType {
   110  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_UINT64)
   111  }
   112  
   113  // FieldTypeSInt64 returns a FieldType for the sint64 scalar type.
   114  func FieldTypeSInt64() *FieldType {
   115  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_SINT64)
   116  }
   117  
   118  // FieldTypeFixed64 returns a FieldType for the fixed64 scalar type.
   119  func FieldTypeFixed64() *FieldType {
   120  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_FIXED64)
   121  }
   122  
   123  // FieldTypeSFixed64 returns a FieldType for the sfixed64 scalar type.
   124  func FieldTypeSFixed64() *FieldType {
   125  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_SFIXED64)
   126  }
   127  
   128  // FieldTypeFloat returns a FieldType for the float scalar type.
   129  func FieldTypeFloat() *FieldType {
   130  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_FLOAT)
   131  }
   132  
   133  // FieldTypeDouble returns a FieldType for the double scalar type.
   134  func FieldTypeDouble() *FieldType {
   135  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_DOUBLE)
   136  }
   137  
   138  // FieldTypeBool returns a FieldType for the bool scalar type.
   139  func FieldTypeBool() *FieldType {
   140  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_BOOL)
   141  }
   142  
   143  // FieldTypeString returns a FieldType for the string scalar type.
   144  func FieldTypeString() *FieldType {
   145  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_STRING)
   146  }
   147  
   148  // FieldTypeBytes returns a FieldType for the bytes scalar type.
   149  func FieldTypeBytes() *FieldType {
   150  	return FieldTypeScalar(descriptorpb.FieldDescriptorProto_TYPE_BYTES)
   151  }
   152  
   153  // FieldTypeMessage returns a FieldType for the given message type.
   154  func FieldTypeMessage(mb *MessageBuilder) *FieldType {
   155  	return &FieldType{
   156  		fieldType:    descriptorpb.FieldDescriptorProto_TYPE_MESSAGE,
   157  		localMsgType: mb,
   158  	}
   159  }
   160  
   161  // FieldTypeImportedMessage returns a FieldType that references the given
   162  // message descriptor.
   163  func FieldTypeImportedMessage(md *desc.MessageDescriptor) *FieldType {
   164  	return &FieldType{
   165  		fieldType:      descriptorpb.FieldDescriptorProto_TYPE_MESSAGE,
   166  		foreignMsgType: md,
   167  	}
   168  }
   169  
   170  // FieldTypeEnum returns a FieldType for the given enum type.
   171  func FieldTypeEnum(eb *EnumBuilder) *FieldType {
   172  	return &FieldType{
   173  		fieldType:     descriptorpb.FieldDescriptorProto_TYPE_ENUM,
   174  		localEnumType: eb,
   175  	}
   176  }
   177  
   178  // FieldTypeImportedEnum returns a FieldType that references the given enum
   179  // descriptor.
   180  func FieldTypeImportedEnum(ed *desc.EnumDescriptor) *FieldType {
   181  	return &FieldType{
   182  		fieldType:       descriptorpb.FieldDescriptorProto_TYPE_ENUM,
   183  		foreignEnumType: ed,
   184  	}
   185  }
   186  
   187  func fieldTypeFromDescriptor(fld *desc.FieldDescriptor) *FieldType {
   188  	switch fld.GetType() {
   189  	case descriptorpb.FieldDescriptorProto_TYPE_GROUP:
   190  		return &FieldType{fieldType: descriptorpb.FieldDescriptorProto_TYPE_GROUP, foreignMsgType: fld.GetMessageType()}
   191  	case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE:
   192  		return FieldTypeImportedMessage(fld.GetMessageType())
   193  	case descriptorpb.FieldDescriptorProto_TYPE_ENUM:
   194  		return FieldTypeImportedEnum(fld.GetEnumType())
   195  	default:
   196  		return FieldTypeScalar(fld.GetType())
   197  	}
   198  }
   199  
   200  // RpcType represents the type of an RPC request or response. The only allowed
   201  // types are messages, but can be streams or unary messages.
   202  //
   203  // Message types can reference a message builder. A type that refers to a built
   204  // message descriptor is called an "imported" type.
   205  //
   206  // To create an RpcType, see RpcTypeMessage and RpcTypeImportedMessage.
   207  type RpcType struct {
   208  	IsStream bool
   209  
   210  	foreignType *desc.MessageDescriptor
   211  	localType   *MessageBuilder
   212  }
   213  
   214  // RpcTypeMessage creates an RpcType that refers to the given message builder.
   215  func RpcTypeMessage(mb *MessageBuilder, stream bool) *RpcType {
   216  	return &RpcType{
   217  		IsStream:  stream,
   218  		localType: mb,
   219  	}
   220  }
   221  
   222  // RpcTypeImportedMessage creates an RpcType that refers to the given message
   223  // descriptor.
   224  func RpcTypeImportedMessage(md *desc.MessageDescriptor, stream bool) *RpcType {
   225  	return &RpcType{
   226  		IsStream:    stream,
   227  		foreignType: md,
   228  	}
   229  }
   230  
   231  // GetTypeName returns the fully qualified name of the message type to which
   232  // this RpcType refers.
   233  func (rt *RpcType) GetTypeName() string {
   234  	if rt.foreignType != nil {
   235  		return rt.foreignType.GetFullyQualifiedName()
   236  	} else {
   237  		return GetFullyQualifiedName(rt.localType)
   238  	}
   239  }