summaryrefslogtreecommitdiffstats
path: root/generator
diff options
context:
space:
mode:
Diffstat (limited to 'generator')
-rwxr-xr-xgenerator/nanopb_generator.py47
-rw-r--r--generator/proto/nanopb.proto4
2 files changed, 40 insertions, 11 deletions
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index 9cf2de5f..185a97bb 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -241,6 +241,11 @@ class Field:
self.enc_size = None
self.ctype = None
+ self.inline = None
+ if field_options.type == nanopb_pb2.FT_INLINE:
+ field_options.type = nanopb_pb2.FT_STATIC
+ self.inline = nanopb_pb2.FT_INLINE
+
# Parse field options
if field_options.HasField("max_size"):
self.max_size = field_options.max_size
@@ -253,16 +258,18 @@ class Field:
# Check field rules, i.e. required/optional/repeated.
can_be_static = True
- if desc.label == FieldD.LABEL_REQUIRED:
- self.rules = 'REQUIRED'
- elif desc.label == FieldD.LABEL_OPTIONAL:
- self.rules = 'OPTIONAL'
- elif desc.label == FieldD.LABEL_REPEATED:
+ 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
+ elif field_options.HasField("proto3"):
+ 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)
@@ -319,7 +326,12 @@ class Field:
elif desc.type == FieldD.TYPE_BYTES:
self.pbtype = 'BYTES'
if self.allocation == 'STATIC':
- self.ctype = self.struct_name + self.name + 't'
+ # Inline STATIC for BYTES is like STATIC for STRING.
+ if self.inline:
+ self.ctype = 'pb_byte_t'
+ self.array_decl += '[%d]' % self.max_size
+ else:
+ self.ctype = self.struct_name + self.name + 't'
self.enc_size = varint_max_size(self.max_size) + self.max_size
elif self.allocation == 'POINTER':
self.ctype = 'pb_bytes_array_t'
@@ -359,7 +371,7 @@ class Field:
def types(self):
'''Return definitions for any special types this field might need.'''
- if self.pbtype == 'BYTES' and self.allocation == 'STATIC':
+ if self.pbtype == 'BYTES' and self.allocation == 'STATIC' and not self.inline:
result = 'typedef PB_BYTES_ARRAY_T(%d) %s;\n' % (self.max_size, self.ctype)
else:
result = ''
@@ -388,7 +400,10 @@ class Field:
if self.pbtype == 'STRING':
inner_init = '""'
elif self.pbtype == 'BYTES':
- inner_init = '{0, {0}}'
+ if self.inline:
+ inner_init = '{0}'
+ else:
+ inner_init = '{0, {0}}'
elif self.pbtype in ('ENUM', 'UENUM'):
inner_init = '(%s)0' % self.ctype
else:
@@ -400,9 +415,15 @@ class Field:
elif self.pbtype == 'BYTES':
data = ['0x%02x' % ord(c) for c in self.default]
if len(data) == 0:
- inner_init = '{0, {0}}'
+ if self.inline:
+ inner_init = '{0}'
+ else:
+ inner_init = '{0, {0}}'
else:
- inner_init = '{%d, {%s}}' % (len(data), ','.join(data))
+ if self.inline:
+ inner_init = '{%s}' % ','.join(data)
+ else:
+ inner_init = '{%d, {%s}}' % (len(data), ','.join(data))
elif self.pbtype in ['FIXED32', 'UINT32']:
inner_init = str(self.default) + 'u'
elif self.pbtype in ['FIXED64', 'UINT64']:
@@ -454,6 +475,8 @@ class Field:
elif self.pbtype == 'BYTES':
if self.allocation != 'STATIC':
return None # Not implemented
+ if self.inline:
+ array_decl = '[%d]' % self.max_size
if declaration_only:
return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl)
@@ -481,7 +504,7 @@ class Field:
result += '%3d, ' % self.tag
result += '%-8s, ' % self.pbtype
result += '%s, ' % self.rules
- result += '%-8s, ' % self.allocation
+ result += '%-8s, ' % (self.allocation if not self.inline else "INLINE")
result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
result += '%s, ' % self.struct_name
result += '%s, ' % self.name
@@ -594,6 +617,7 @@ class ExtensionRange(Field):
self.default = None
self.max_size = 0
self.max_count = 0
+ self.inline = None
def __str__(self):
return ' pb_extension_t *extensions;'
@@ -671,6 +695,7 @@ class OneOf(Field):
self.default = None
self.rules = 'ONEOF'
self.anonymous = False
+ self.inline = None
def add_field(self, field):
if field.allocation == 'CALLBACK':
diff --git a/generator/proto/nanopb.proto b/generator/proto/nanopb.proto
index 9b2f0fbc..b9961c88 100644
--- a/generator/proto/nanopb.proto
+++ b/generator/proto/nanopb.proto
@@ -16,6 +16,7 @@ enum FieldType {
FT_POINTER = 4; // Always generate a dynamically allocated field.
FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
FT_IGNORE = 3; // Ignore the field completely.
+ FT_INLINE = 5; // Always generate an inline array of fixed size.
}
enum IntSize {
@@ -65,6 +66,9 @@ message NanoPBOptions {
// decode oneof as anonymous union
optional bool anonymous_oneof = 11 [default = false];
+
+ // Proto3 singular field does not generate a "has_" flag
+ optional bool proto3 = 12 [default = false];
}
// Extensions to protoc 'Descriptor' type in order to define options