parameters: (self, struct_name, desc, field_options)
docstring: desc is FieldDescriptorProto
docstring_summary: desc is FieldDescriptorProto
docstring_tokens: desc is FieldDescriptorProto
function: def __init__(self, struct_name, desc, field_options):
          '''desc is FieldDescriptorProto'''
          self.tag = desc.number
          self.struct_name = struct_name
          self.union_name = None
          self.name = desc.name
          self.default = None
          self.max_size = None
          self.max_count = None
          self.array_decl = ""
          self.enc_size = None
          self.data_item_size = None
          self.ctype = None
          self.fixed_count = False
          self.callback_datatype = field_options.callback_datatype
          self.math_include_required = False
          self.sort_by_tag = field_options.sort_by_tag
  
          if field_options.type == nanopb_pb2.FT_INLINE:
              # Before nanopb-0.3.8, fixed length bytes arrays were specified
              # by setting type to FT_INLINE. But to handle pointer typed fields,
              # it makes sense to have it as a separate option.
              field_options.type = nanopb_pb2.FT_STATIC
              field_options.fixed_length = True
  
          # Parse field options
          if field_options.HasField("max_size"):
              self.max_size = field_options.max_size
  
          self.default_has = field_options.default_has
  
          if desc.type == FieldD.TYPE_STRING and field_options.HasField("max_length"):
              # max_length overrides max_size for strings
              self.max_size = field_options.max_length + 1
  
          if field_options.HasField("max_count"):
              self.max_count = field_options.max_count
  
          if desc.HasField('default_value'):
              self.default = desc.default_value
  
          # Check field rules, i.e. required/optional/repeated.
          can_be_static = True
          if desc.label == FieldD.LABEL_REPEATED:
              self.rules = 'REPEATED'
              if self.max_count is None:
                  can_be_static = False
              else:
                  self.array_decl = '[%d]' % self.max_count
                  if field_options.fixed_count:
                    self.rules = 'FIXARRAY'
  
          elif field_options.proto3:
              if desc.type == FieldD.TYPE_MESSAGE and not field_options.proto3_singular_msgs:
                  # In most other protobuf libraries proto3 submessages have
                  # "null" status. For nanopb, that is implemented as has_ field.
                  self.rules = 'OPTIONAL'
              else:
                  self.rules = 'SINGULAR'
          elif desc.label == FieldD.LABEL_REQUIRED:
              self.rules = 'REQUIRED'
          elif desc.label == FieldD.LABEL_OPTIONAL:
              self.rules = 'OPTIONAL'
          else:
              raise NotImplementedError(desc.label)
  
          # Check if the field can be implemented with static allocation
          # i.e. whether the data size is known.
          if desc.type == FieldD.TYPE_STRING and self.max_size is None:
              can_be_static = False
  
          if desc.type == FieldD.TYPE_BYTES and self.max_size is None:
              can_be_static = False
  
          # Decide how the field data will be allocated
          if field_options.type == nanopb_pb2.FT_DEFAULT:
              if can_be_static:
                  field_options.type = nanopb_pb2.FT_STATIC
              else:
                  field_options.type = nanopb_pb2.FT_CALLBACK
  
          if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static:
              raise Exception("Field '%s' is defined as static, but max_size or "
                              "max_count is not given." % self.name)
  
          if field_options.fixed_count and self.max_count is None:
              raise Exception("Field '%s' is defined as fixed count, "
                              "but max_count is not given." % self.name)
  
          if field_options.type == nanopb_pb2.FT_STATIC:
              self.allocation = 'STATIC'
          elif field_options.type == nanopb_pb2.FT_POINTER:
              self.allocation = 'POINTER'
          elif field_options.type == nanopb_pb2.FT_CALLBACK:
              self.allocation = 'CALLBACK'
          else:
              raise NotImplementedError(field_options.type)
  
          if field_options.HasField("type_override"):
              desc.type = field_options.type_override
  
          # Decide the C data type to use in the struct.
          if desc.type in datatypes:
              self.ctype, self.pbtype, self.enc_size, self.data_item_size = datatypes[desc.type]
  
              # Override the field size if user wants to use smaller integers
              if (desc.type, field_options.int_size) in datatypes:
                  self.ctype, self.pbtype, self.enc_size, self.data_item_size = datatypes[(desc.type, field_options.int_size)]
          elif desc.type == FieldD.TYPE_ENUM:
              self.pbtype = 'ENUM'
              self.data_item_size = 4
              self.ctype = names_from_type_name(desc.type_name)
              if self.default is not None:
                  self.default = self.ctype + self.default
              self.enc_size = None # Needs to be filled in when enum values are known
          elif desc.type == FieldD.TYPE_STRING:
              self.pbtype = 'STRING'
              self.ctype = 'char'
              if self.allocation == 'STATIC':
                  self.ctype = 'char'
                  self.array_decl += '[%d]' % self.max_size
                  # -1 because of null terminator. Both pb_encode and pb_decode
                  # check the presence of it.
                  self.enc_size = varint_max_size(self.max_size) + self.max_size - 1
          elif desc.type == FieldD.TYPE_BYTES:
              if field_options.fixed_length:
                  self.pbtype = 'FIXED_LENGTH_BYTES'
  
                  if self.max_size is None:
                      raise Exception("Field '%s' is defined as fixed length, "
                                      "but max_size is not given." % self.name)
  
                  self.enc_size = varint_max_size(self.max_size) + self.max_size
                  self.ctype = 'pb_byte_t'
                  self.array_decl += '[%d]' % self.max_size
              else:
                  self.pbtype = 'BYTES'
                  self.ctype = 'pb_bytes_array_t'
                  if self.allocation == 'STATIC':
                      self.ctype = self.struct_name + self.name + 't'
                      self.enc_size = varint_max_size(self.max_size) + self.max_size
          elif desc.type == FieldD.TYPE_MESSAGE:
              self.pbtype = 'MESSAGE'
              self.ctype = self.submsgname = names_from_type_name(desc.type_name)
              self.enc_size = None # Needs to be filled in after the message type is available
              if field_options.submsg_callback:
                  self.pbtype = 'MSG_W_CB'
          else:
              raise NotImplementedError(desc.type)
  
          if self.default and self.pbtype in ['FLOAT', 'DOUBLE']:
              if 'inf' in self.default or 'nan' in self.default:
                  self.math_include_required = True
function_tokens: def __init__ ( self , struct_name , desc , field_options ) : self . tag = desc . number self . struct_name = struct_name self . union_name = None self . name = desc . name self . default = None self . max_size = None self . max_count = None self . array_decl = "" self . enc_size = None self . data_item_size = None self . ctype = None self . fixed_count = False self . callback_datatype = field_options . callback_datatype self . math_include_required = False self . sort_by_tag = field_options . sort_by_tag if field_options . type == nanopb_pb2 . FT_INLINE : # Before nanopb-0.3.8, fixed length bytes arrays were specified # by setting type to FT_INLINE. But to handle pointer typed fields, # it makes sense to have it as a separate option. field_options . type = nanopb_pb2 . FT_STATIC field_options . fixed_length = True # Parse field options if field_options . HasField ( "max_size" ) : self . max_size = field_options . max_size self . default_has = field_options . default_has if desc . type == FieldD . TYPE_STRING and field_options . HasField ( "max_length" ) : # max_length overrides max_size for strings self . max_size = field_options . max_length + 1 if field_options . HasField ( "max_count" ) : self . max_count = field_options . max_count if desc . HasField ( 'default_value' ) : self . default = desc . default_value # Check field rules, i.e. required/optional/repeated. can_be_static = True if desc . label == FieldD . LABEL_REPEATED : self . rules = 'REPEATED' if self . max_count is None : can_be_static = False else : self . array_decl = '[%d]' % self . max_count if field_options . fixed_count : self . rules = 'FIXARRAY' elif field_options . proto3 : if desc . type == FieldD . TYPE_MESSAGE and not field_options . proto3_singular_msgs : # In most other protobuf libraries proto3 submessages have # "null" status. For nanopb, that is implemented as has_ field. self . rules = 'OPTIONAL' else : self . rules = 'SINGULAR' elif desc . label == FieldD . LABEL_REQUIRED : self . rules = 'REQUIRED' elif desc . label == FieldD . LABEL_OPTIONAL : self . rules = 'OPTIONAL' else : raise NotImplementedError ( desc . label ) # Check if the field can be implemented with static allocation # i.e. whether the data size is known. if desc . type == FieldD . TYPE_STRING and self . max_size is None : can_be_static = False if desc . type == FieldD . TYPE_BYTES and self . max_size is None : can_be_static = False # Decide how the field data will be allocated if field_options . type == nanopb_pb2 . FT_DEFAULT : if can_be_static : field_options . type = nanopb_pb2 . FT_STATIC else : field_options . type = nanopb_pb2 . FT_CALLBACK if field_options . type == nanopb_pb2 . FT_STATIC and not can_be_static : raise Exception ( "Field '%s' is defined as static, but max_size or " "max_count is not given." % self . name ) if field_options . fixed_count and self . max_count is None : raise Exception ( "Field '%s' is defined as fixed count, " "but max_count is not given." % self . name ) if field_options . type == nanopb_pb2 . FT_STATIC : self . allocation = 'STATIC' elif field_options . type == nanopb_pb2 . FT_POINTER : self . allocation = 'POINTER' elif field_options . type == nanopb_pb2 . FT_CALLBACK : self . allocation = 'CALLBACK' else : raise NotImplementedError ( field_options . type ) if field_options . HasField ( "type_override" ) : desc . type = field_options . type_override # Decide the C data type to use in the struct. if desc . type in datatypes : self . ctype , self . pbtype , self . enc_size , self . data_item_size = datatypes [ desc . type ] # Override the field size if user wants to use smaller integers if ( desc . type , field_options . int_size ) in datatypes : self . ctype , self . pbtype , self . enc_size , self . data_item_size = datatypes [ ( desc . type , field_options . int_size ) ] elif desc . type == FieldD . TYPE_ENUM : self . pbtype = 'ENUM' self . data_item_size = 4 self . ctype = names_from_type_name ( desc . type_name ) if self . default is not None : self . default = self . ctype + self . default self . enc_size = None # Needs to be filled in when enum values are known elif desc . type == FieldD . TYPE_STRING : self . pbtype = 'STRING' self . ctype = 'char' if self . allocation == 'STATIC' : self . ctype = 'char' self . array_decl += '[%d]' % self . max_size # -1 because of null terminator. Both pb_encode and pb_decode # check the presence of it. self . enc_size = varint_max_size ( self . max_size ) + self . max_size - 1 elif desc . type == FieldD . TYPE_BYTES : if field_options . fixed_length : self . pbtype = 'FIXED_LENGTH_BYTES' if self . max_size is None : raise Exception ( "Field '%s' is defined as fixed length, " "but max_size is not given." % self . name ) self . enc_size = varint_max_size ( self . max_size ) + self . max_size self . ctype = 'pb_byte_t' self . array_decl += '[%d]' % self . max_size else : self . pbtype = 'BYTES' self . ctype = 'pb_bytes_array_t' if self . allocation == 'STATIC' : self . ctype = self . struct_name + self . name + 't' self . enc_size = varint_max_size ( self . max_size ) + self . max_size elif desc . type == FieldD . TYPE_MESSAGE : self . pbtype = 'MESSAGE' self . ctype = self . submsgname = names_from_type_name ( desc . type_name ) self . enc_size = None # Needs to be filled in after the message type is available if field_options . submsg_callback : self . pbtype = 'MSG_W_CB' else : raise NotImplementedError ( desc . type ) if self . default and self . pbtype in [ 'FLOAT' , 'DOUBLE' ] : if 'inf' in self . default or 'nan' in self . default : self . math_include_required = True