go_helpers.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. from stone.api import ApiNamespace
  2. from stone.data_type import (
  3. Boolean,
  4. Float32,
  5. Float64,
  6. Int32,
  7. Int64,
  8. String,
  9. Timestamp,
  10. UInt32,
  11. UInt64,
  12. unwrap_nullable,
  13. is_composite_type,
  14. is_list_type,
  15. is_struct_type,
  16. Void,
  17. )
  18. from stone.target import helpers
  19. HEADER = """\
  20. // Copyright (c) Dropbox, Inc.
  21. //
  22. // Permission is hereby granted, free of charge, to any person obtaining a copy
  23. // of this software and associated documentation files (the "Software"), to deal
  24. // in the Software without restriction, including without limitation the rights
  25. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  26. // copies of the Software, and to permit persons to whom the Software is
  27. // furnished to do so, subject to the following conditions:
  28. //
  29. // The above copyright notice and this permission notice shall be included in
  30. // all copies or substantial portions of the Software.
  31. //
  32. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  33. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  34. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  35. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  36. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  37. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  38. // THE SOFTWARE.
  39. """
  40. _reserved_keywords = {
  41. 'break', 'default', 'func', 'interface', 'select',
  42. 'case', 'defer', 'go', 'map', 'struct',
  43. 'chan', 'else', 'goto', 'package', 'switch',
  44. 'const', 'fallthrough', 'if', 'range', 'type',
  45. 'continue', 'for', 'import', 'return', 'var',
  46. }
  47. _type_table = {
  48. UInt64: 'uint64',
  49. Int64: 'int64',
  50. UInt32: 'uint32',
  51. Int32: 'int32',
  52. Float64: 'float64',
  53. Float32: 'float32',
  54. Boolean: 'bool',
  55. String: 'string',
  56. Timestamp: 'time.Time',
  57. Void: 'struct{}',
  58. }
  59. def _rename_if_reserved(s):
  60. if s in _reserved_keywords:
  61. return s + '_'
  62. else:
  63. return s
  64. def fmt_type(data_type, namespace=None, use_interface=False):
  65. data_type, nullable = unwrap_nullable(data_type)
  66. if is_list_type(data_type):
  67. return '[]%s' % fmt_type(data_type.data_type, namespace, use_interface)
  68. type_name = data_type.name
  69. if use_interface and _needs_base_type(data_type):
  70. type_name = 'Is' + type_name
  71. if is_composite_type(data_type) and namespace is not None and \
  72. namespace.name != data_type.namespace.name:
  73. type_name = data_type.namespace.name + '.' + type_name
  74. if use_interface and _needs_base_type(data_type):
  75. return _type_table.get(data_type.__class__, type_name)
  76. else:
  77. return _type_table.get(data_type.__class__, '*' + type_name)
  78. def fmt_var(name, export=True, check_reserved=False):
  79. s = helpers.fmt_pascal(name) if export else helpers.fmt_camel(name)
  80. return _rename_if_reserved(s) if check_reserved else s
  81. def _doc_handler(tag, val):
  82. if tag == 'type':
  83. return '`{}`'.format(val)
  84. elif tag == 'route':
  85. return '`{}`'.format(helpers.fmt_camel(val))
  86. elif tag == 'link':
  87. anchor, link = val.rsplit(' ', 1)
  88. return '`{}` <{}>'.format(anchor, link)
  89. elif tag == 'val':
  90. if val == 'null':
  91. return 'nil'
  92. else:
  93. return val
  94. elif tag == 'field':
  95. return '`{}`'.format(val)
  96. else:
  97. raise RuntimeError('Unknown doc ref tag %r' % tag)
  98. def generate_doc(code_generator, t):
  99. doc = t.doc
  100. if doc is None:
  101. doc = 'has no documentation (yet)'
  102. doc = code_generator.process_doc(doc, _doc_handler)
  103. d = '%s : %s' % (fmt_var(t.name), doc)
  104. if isinstance(t, ApiNamespace):
  105. d = 'Package %s : %s' % (t.name, doc)
  106. code_generator.emit_wrapped_text(d, prefix='// ')
  107. def _needs_base_type(data_type):
  108. if is_struct_type(data_type) and data_type.has_enumerated_subtypes():
  109. return True
  110. if is_list_type(data_type):
  111. return _needs_base_type(data_type.data_type)
  112. return False
  113. def needs_base_type(struct):
  114. for field in struct.fields:
  115. if _needs_base_type(field.data_type):
  116. return True
  117. return False