aws-sdk-code-generator 0.1.0.pre → 0.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/lib/aws-sdk-code-generator.rb +68 -75
  3. data/lib/aws-sdk-code-generator/api.rb +130 -0
  4. data/lib/aws-sdk-code-generator/apply_docs.rb +15 -2
  5. data/lib/aws-sdk-code-generator/client_constructor.rb +39 -0
  6. data/lib/aws-sdk-code-generator/client_operation_documentation.rb +268 -0
  7. data/lib/aws-sdk-code-generator/client_operation_list.rb +148 -0
  8. data/lib/aws-sdk-code-generator/client_response_structure_example.rb +108 -0
  9. data/lib/aws-sdk-code-generator/code_builder.rb +146 -133
  10. data/lib/aws-sdk-code-generator/crosslink.rb +42 -0
  11. data/lib/aws-sdk-code-generator/docstring.rb +199 -0
  12. data/lib/aws-sdk-code-generator/error_list.rb +77 -0
  13. data/lib/aws-sdk-code-generator/errors.rb +2 -0
  14. data/lib/aws-sdk-code-generator/eventstream_example.rb +220 -0
  15. data/lib/aws-sdk-code-generator/gem_builder.rb +19 -25
  16. data/lib/aws-sdk-code-generator/hash_formatter.rb +5 -2
  17. data/lib/aws-sdk-code-generator/helper.rb +77 -61
  18. data/lib/aws-sdk-code-generator/plugin_list.rb +146 -0
  19. data/lib/aws-sdk-code-generator/resource_action.rb +69 -0
  20. data/lib/aws-sdk-code-generator/resource_action_code.rb +57 -0
  21. data/lib/aws-sdk-code-generator/resource_association.rb +37 -0
  22. data/lib/aws-sdk-code-generator/resource_attribute.rb +76 -0
  23. data/lib/aws-sdk-code-generator/resource_batch_action.rb +56 -0
  24. data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +136 -0
  25. data/lib/aws-sdk-code-generator/resource_batch_action_documentation.rb +108 -0
  26. data/lib/aws-sdk-code-generator/resource_batch_builder.rb +212 -0
  27. data/lib/aws-sdk-code-generator/resource_builder.rb +48 -0
  28. data/lib/aws-sdk-code-generator/resource_client_request.rb +62 -0
  29. data/lib/aws-sdk-code-generator/resource_client_request_documentation.rb +81 -0
  30. data/lib/aws-sdk-code-generator/resource_client_request_params.rb +86 -0
  31. data/lib/aws-sdk-code-generator/resource_data_method.rb +60 -0
  32. data/lib/aws-sdk-code-generator/resource_has_association.rb +117 -0
  33. data/lib/aws-sdk-code-generator/resource_has_many_association.rb +52 -0
  34. data/lib/aws-sdk-code-generator/resource_has_many_association_code.rb +76 -0
  35. data/lib/aws-sdk-code-generator/resource_identifier.rb +44 -0
  36. data/lib/aws-sdk-code-generator/resource_identifiers_method.rb +29 -0
  37. data/lib/aws-sdk-code-generator/resource_load_method.rb +68 -0
  38. data/lib/aws-sdk-code-generator/resource_method.rb +22 -0
  39. data/lib/aws-sdk-code-generator/resource_skip_params.rb +36 -0
  40. data/lib/aws-sdk-code-generator/resource_value_source.rb +68 -0
  41. data/lib/aws-sdk-code-generator/resource_waiter.rb +80 -0
  42. data/lib/aws-sdk-code-generator/service.rb +30 -7
  43. data/lib/aws-sdk-code-generator/shared_example.rb +131 -0
  44. data/lib/aws-sdk-code-generator/syntax_example.rb +60 -0
  45. data/lib/aws-sdk-code-generator/syntax_example_hash.rb +174 -0
  46. data/lib/aws-sdk-code-generator/underscore.rb +10 -5
  47. data/lib/aws-sdk-code-generator/view.rb +33 -0
  48. data/lib/aws-sdk-code-generator/views.rb +2 -0
  49. data/lib/aws-sdk-code-generator/views/apig_endpoint_class.rb +25 -0
  50. data/lib/aws-sdk-code-generator/views/apig_readme.rb +32 -0
  51. data/lib/aws-sdk-code-generator/views/async_client_class.rb +68 -0
  52. data/lib/aws-sdk-code-generator/views/authorizer_class.rb +17 -0
  53. data/lib/aws-sdk-code-generator/views/client_api_module.rb +583 -0
  54. data/lib/aws-sdk-code-generator/views/client_class.rb +93 -0
  55. data/lib/aws-sdk-code-generator/views/docstring.rb +27 -0
  56. data/lib/aws-sdk-code-generator/views/errors_module.rb +32 -0
  57. data/lib/aws-sdk-code-generator/views/event_streams_module.rb +149 -0
  58. data/lib/aws-sdk-code-generator/views/features/env.rb +9 -0
  59. data/lib/aws-sdk-code-generator/views/features/smoke.rb +51 -0
  60. data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +26 -0
  61. data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +2 -0
  62. data/lib/aws-sdk-code-generator/views/gemspec.rb +39 -5
  63. data/lib/aws-sdk-code-generator/views/resource_class.rb +122 -0
  64. data/lib/aws-sdk-code-generator/views/root_resource_class.rb +58 -0
  65. data/lib/aws-sdk-code-generator/views/service_module.rb +30 -14
  66. data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +9 -0
  67. data/lib/aws-sdk-code-generator/views/types_module.rb +294 -0
  68. data/lib/aws-sdk-code-generator/views/version.rb +2 -0
  69. data/lib/aws-sdk-code-generator/views/waiters_module.rb +37 -0
  70. data/lib/aws-sdk-code-generator/waiter.rb +95 -0
  71. data/lib/aws-sdk-code-generator/yard_option_tag.rb +43 -0
  72. metadata +61 -68
  73. data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +0 -23
  74. data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +0 -43
  75. data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +0 -11
  76. data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +0 -11
  77. data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +0 -15
  78. data/lib/aws-sdk-code-generator/dsl/block_param.rb +0 -11
  79. data/lib/aws-sdk-code-generator/dsl/class.rb +0 -27
  80. data/lib/aws-sdk-code-generator/dsl/code_literal.rb +0 -66
  81. data/lib/aws-sdk-code-generator/dsl/code_object.rb +0 -33
  82. data/lib/aws-sdk-code-generator/dsl/docstring.rb +0 -36
  83. data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +0 -15
  84. data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +0 -12
  85. data/lib/aws-sdk-code-generator/dsl/formatter.rb +0 -25
  86. data/lib/aws-sdk-code-generator/dsl/include_statement.rb +0 -17
  87. data/lib/aws-sdk-code-generator/dsl/main.rb +0 -105
  88. data/lib/aws-sdk-code-generator/dsl/method.rb +0 -108
  89. data/lib/aws-sdk-code-generator/dsl/module.rb +0 -167
  90. data/lib/aws-sdk-code-generator/dsl/option_tag.rb +0 -36
  91. data/lib/aws-sdk-code-generator/dsl/param.rb +0 -43
  92. data/lib/aws-sdk-code-generator/dsl/param_list.rb +0 -38
  93. data/lib/aws-sdk-code-generator/dsl/return_tag.rb +0 -19
  94. data/lib/aws-sdk-code-generator/dsl/tag_default.rb +0 -20
  95. data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +0 -27
  96. data/lib/aws-sdk-code-generator/dsl/tag_type.rb +0 -18
  97. data/lib/aws-sdk-code-generator/generators/client_api_module.rb +0 -334
  98. data/lib/aws-sdk-code-generator/generators/client_class.rb +0 -389
  99. data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +0 -166
  100. data/lib/aws-sdk-code-generator/generators/errors_module.rb +0 -25
  101. data/lib/aws-sdk-code-generator/generators/resource/action.rb +0 -88
  102. data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +0 -211
  103. data/lib/aws-sdk-code-generator/generators/resource/builder.rb +0 -50
  104. data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +0 -15
  105. data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +0 -49
  106. data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +0 -97
  107. data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +0 -88
  108. data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +0 -180
  109. data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +0 -24
  110. data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +0 -18
  111. data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +0 -49
  112. data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +0 -29
  113. data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +0 -32
  114. data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +0 -101
  115. data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +0 -108
  116. data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +0 -26
  117. data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +0 -28
  118. data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +0 -67
  119. data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +0 -65
  120. data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +0 -68
  121. data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +0 -61
  122. data/lib/aws-sdk-code-generator/generators/resource_class.rb +0 -325
  123. data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +0 -83
  124. data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +0 -42
  125. data/lib/aws-sdk-code-generator/generators/service_documentation.rb +0 -64
  126. data/lib/aws-sdk-code-generator/generators/shared_example.rb +0 -132
  127. data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +0 -95
  128. data/lib/aws-sdk-code-generator/generators/syntax_example.rb +0 -169
  129. data/lib/aws-sdk-code-generator/generators/types_module.rb +0 -52
  130. data/lib/aws-sdk-code-generator/generators/waiter_class.rb +0 -62
  131. data/lib/aws-sdk-code-generator/generators/waiters_module.rb +0 -20
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module Views
5
+ class ResourceClass < View
6
+
7
+ def initialize(options)
8
+ @module_name = options.fetch(:module_name)
9
+ @class_name = options.fetch(:class_name)
10
+ api = options.fetch(:api)
11
+ resource = options.fetch(:resource)
12
+ @identifiers = ResourceIdentifier.build_list(resource)
13
+ @identifiers_method = ResourceIdentifiersMethod.build(@identifiers)
14
+ @data_attributes = ResourceAttribute.build_list(resource, api)
15
+ @load_method = ResourceLoadMethod.build(@class_name, resource)
16
+ @data_method = ResourceDataMethod.build(@class_name, resource)
17
+ @client_load_method = Underscore.underscore(resource['load']['request']['operation']) if resource['load']
18
+ @data_class = "Types::#{resource['shape']}"
19
+ @waiters = ResourceWaiter.build_list(resource, options[:waiters])
20
+ @wait_until = options[:waiters] # add #wait_until method if service has waiters
21
+ @actions = ResourceAction.build_list(@class_name, resource, api)
22
+ @associations = build_associations(options)
23
+ @batch_actions = ResourceBatchAction.build_list(@class_name, resource, api)
24
+ @shape = resource['shape']
25
+ @custom = options.fetch(:custom)
26
+ end
27
+
28
+ # @return [String]
29
+ attr_reader :module_name
30
+
31
+ # @return [String]
32
+ attr_reader :class_name
33
+
34
+ # @return [Array<ResourceIdentifier>]
35
+ attr_reader :identifiers
36
+
37
+ # @return [String]
38
+ attr_reader :identifiers_method
39
+
40
+ # @return [Array<ResourceAttribute>]
41
+ attr_reader :data_attributes
42
+
43
+ # @return [String]
44
+ attr_reader :data_class
45
+
46
+ # @return [String]
47
+ attr_reader :load_method
48
+
49
+ # @return [String]
50
+ attr_reader :data_method
51
+
52
+ # @return [String, nil]
53
+ attr_reader :client_load_method
54
+
55
+ # @return [Array<Waiter>]
56
+ attr_reader :waiters
57
+
58
+ # @return [Boolean]
59
+ attr_reader :wait_until
60
+
61
+ # @return [Array<ResourceAction>]
62
+ attr_reader :actions
63
+
64
+ # @return [Array<ResourceAssociation>]
65
+ attr_reader :associations
66
+
67
+ # @return [Array<ResourceBatchAction>]
68
+ attr_reader :batch_actions
69
+
70
+ # @return [String, nil]
71
+ attr_reader :shape
72
+
73
+ # @return [String|nil]
74
+ def generated_src_warning
75
+ return if @custom
76
+ GENERATED_SRC_WARNING
77
+ end
78
+
79
+ # @return [Boolean]
80
+ def waiters?
81
+ !@waiters.empty?
82
+ end
83
+
84
+ # @return [ResoruceWiater, nil]
85
+ def exists_waiter
86
+ @waiters.find { |w| w.name == 'exists' }
87
+ end
88
+
89
+ # @return [Boolean]
90
+ def actions?
91
+ actions.size > 0
92
+ end
93
+
94
+ # @return [Boolean]
95
+ def associations?
96
+ associations.size > 0
97
+ end
98
+
99
+ # @return [Boolean]
100
+ def batch_actions?
101
+ batch_actions.size > 0
102
+ end
103
+
104
+ # @return [Boolean]
105
+ def identifiers?
106
+ @identifiers.size > 0
107
+ end
108
+
109
+ private
110
+
111
+ def build_associations(options)
112
+ ResourceAssociation.build_list(
113
+ class_name: options.fetch(:class_name),
114
+ resource: options.fetch(:resource),
115
+ api: options.fetch(:api),
116
+ paginators: options.fetch(:paginators)
117
+ )
118
+ end
119
+
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ module Views
5
+ class RootResourceClass < View
6
+
7
+ def initialize(options)
8
+ @module_name = options.fetch(:module_name)
9
+ @service_name = options.fetch(:service_name)
10
+ class_name = @module_name.split('::').last
11
+ api = options.fetch(:api)
12
+ resource = (options[:resources] || {})['service'] || {}
13
+ @actions = ResourceAction.build_list(class_name, resource, api)
14
+ @associations = ResourceAssociation.build_list(
15
+ class_name: class_name,
16
+ resource: resource,
17
+ api: api,
18
+ paginators: options.fetch(:paginators)
19
+ )
20
+ @custom = options.fetch(:custom)
21
+ end
22
+
23
+ # @return [String]
24
+ attr_reader :module_name
25
+
26
+ # @return [Array<ResourceAction>]
27
+ attr_reader :actions
28
+
29
+ # @return [Array<ResourceAssociation>]
30
+ attr_reader :associations
31
+
32
+ # @return [String]
33
+ attr_reader :service_name
34
+
35
+ # @return [String|nil]
36
+ def generated_src_warning
37
+ return if @custom
38
+ GENERATED_SRC_WARNING
39
+ end
40
+
41
+ # @return [Boolean]
42
+ def actions?
43
+ actions.size > 0
44
+ end
45
+
46
+ # @return [Boolean]
47
+ def associations?
48
+ associations.size > 0
49
+ end
50
+
51
+ # @return [Boolean]
52
+ def documentation?
53
+ actions? || associations?
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module AwsSdkCodeGenerator
@@ -5,11 +7,18 @@ module AwsSdkCodeGenerator
5
7
  class ServiceModule < View
6
8
 
7
9
  # @option options [required, Service] :service
10
+ # @option options [required, String] :prefix
8
11
  def initialize(options)
9
12
  @service = options.fetch(:service)
10
13
  @prefix = options.fetch(:prefix)
11
14
  end
12
15
 
16
+ # @return [String|nil]
17
+ def generated_src_warning
18
+ return if @service.protocol == 'api-gateway'
19
+ GENERATED_SRC_WARNING
20
+ end
21
+
13
22
  def full_name
14
23
  @service.full_name
15
24
  end
@@ -45,15 +54,15 @@ module AwsSdkCodeGenerator
45
54
  # @return [Array<String>]
46
55
  def relative_requires
47
56
  paths = Set.new
48
- paths << "#{prefix}/types"
49
- paths << "#{prefix}/client_api"
50
- paths << "#{prefix}/client"
51
- paths << "#{prefix}/errors"
52
- paths << "#{prefix}/waiters" if @service.waiters
53
- paths << "#{prefix}/resource"
57
+ paths << "#{@prefix}/types"
58
+ paths << "#{@prefix}/client_api"
59
+ paths << "#{@prefix}/client"
60
+ paths << "#{@prefix}/errors"
61
+ paths << "#{@prefix}/waiters" if @service.waiters
62
+ paths << "#{@prefix}/resource"
54
63
  if @service.resources && @service.resources['resources']
55
64
  @service.resources['resources'].keys.each do |resource_name|
56
- path = "#{prefix}/#{underscore(resource_name)}"
65
+ path = "#{@prefix}/#{underscore(resource_name)}"
57
66
  if paths.include?(path)
58
67
  raise "resource path conflict for `#{resource_name}'"
59
68
  else
@@ -61,7 +70,14 @@ module AwsSdkCodeGenerator
61
70
  end
62
71
  end
63
72
  end
64
- paths << "#{prefix}/customizations"
73
+ paths << "#{@prefix}/customizations"
74
+ if @service.api['metadata']['protocolSettings'] &&
75
+ @service.api['metadata']['protocolSettings']['h2'] == 'eventstream'
76
+ paths << "#{@prefix}/async_client"
77
+ paths << "#{@prefix}/event_streams"
78
+ elsif eventstream_shape?
79
+ paths << "#{@prefix}/event_streams"
80
+ end
65
81
  paths.to_a
66
82
  end
67
83
 
@@ -70,16 +86,16 @@ module AwsSdkCodeGenerator
70
86
  end
71
87
 
72
88
  def example_operation_name
89
+ raise "no operations found for the service" if @service.api['operations'].empty?
73
90
  underscore(@service.api['operations'].keys.first)
74
- nil
75
91
  end
76
92
 
77
- private
78
-
79
- def prefix
80
- @prefix
93
+ def eventstream_shape?
94
+ @service.api['shapes'].each do |_, shape_ref|
95
+ return true if shape_ref['eventstream']
96
+ end
97
+ false
81
98
  end
82
-
83
99
  end
84
100
  end
85
101
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsSdkCodeGenerator
2
4
  module Views
3
5
  module Spec
@@ -13,11 +15,18 @@ module AwsSdkCodeGenerator
13
15
  @gem_dependencies = service.gem_dependencies.map do |gem_name, _|
14
16
  { dependency: gem_name }
15
17
  end
18
+ @custom = service.protocol == 'api-gateway'
16
19
  end
17
20
 
18
21
  attr_reader :gem_name
19
22
  attr_reader :gem_dependencies
20
23
 
24
+ # @return [String|nil]
25
+ def generated_src_warning
26
+ return if @custom
27
+ GENERATED_SRC_WARNING
28
+ end
29
+
21
30
  end
22
31
  end
23
32
  end
@@ -0,0 +1,294 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module AwsSdkCodeGenerator
6
+ module Views
7
+ class TypesModule < View
8
+
9
+ include Helper
10
+
11
+ # @option options [required, Service] :service
12
+ def initialize(options)
13
+ @service = options.fetch(:service)
14
+ @api = @service.api
15
+ @input_shapes = compute_input_shapes(@service.api)
16
+ end
17
+
18
+ # @return [String|nil]
19
+ def generated_src_warning
20
+ return if @service.protocol == 'api-gateway'
21
+ GENERATED_SRC_WARNING
22
+ end
23
+
24
+ def module_name
25
+ @service.module_name
26
+ end
27
+
28
+ # @return [Array<StructClass>]
29
+ def structures
30
+ unless @service.protocol_settings.empty?
31
+ if @service.protocol_settings['h2'] == 'eventstream'
32
+ @service.api['shapes'].each do |_, shape|
33
+ if shape['eventstream']
34
+ # add event trait to all members if not exists
35
+ shape['members'].each do |name, ref|
36
+ @service.api['shapes'][ref['shape']]['event'] = true
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ @service.api['shapes'].inject([]) do |list, (shape_name, shape)|
43
+ # APIG model can have input/output shape with downcase and '__'
44
+ if @service.protocol == 'api-gateway'
45
+ shape_name = lstrip_prefix(upcase_first(shape_name))
46
+ end
47
+ # eventstream shape will be inheriting from enumerator
48
+ if shape['eventstream']
49
+ list
50
+ elsif shape['type'] == 'structure'
51
+ struct_members = struct_members(shape)
52
+ sensitive_params = struct_members.select(&:sensitive).map do |m|
53
+ m.member_name.to_sym
54
+ end
55
+ list << StructClass.new(
56
+ class_name: shape_name,
57
+ members: struct_members,
58
+ sensitive_params: sensitive_params,
59
+ documentation: struct_class_docs(shape_name)
60
+ )
61
+ else
62
+ list
63
+ end
64
+ end
65
+ end
66
+
67
+ # return [Array<EventStreamClass>]
68
+ def eventstreams
69
+ @service.api['shapes'].inject([]) do |list, (shape_name, shape)|
70
+ if shape['eventstream']
71
+ list << EventStreamClass.new(
72
+ class_name: shape_name,
73
+ types: struct_members(shape),
74
+ documentation: eventstream_class_docs(shape_name)
75
+ )
76
+ else
77
+ list
78
+ end
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def struct_members(shape)
85
+ return if shape['members'].nil?
86
+ members = shape['members'].map do |member_name, member_ref|
87
+ sensitive = !!(member_ref['sensitive'] ||
88
+ @api['shapes'][member_ref['shape']]['sensitive'])
89
+ StructMember.new(
90
+ member_name: underscore(member_name),
91
+ sensitive: sensitive
92
+ )
93
+ end
94
+ if shape['event']
95
+ members << StructMember.new(member_name: 'event_type')
96
+ end
97
+ members
98
+ end
99
+
100
+ def struct_class_docs(shape_name)
101
+ join_docstrings([
102
+ html_to_markdown(Api.docstring(shape_name, @api)),
103
+ input_example_docs(shape_name),
104
+ attribute_macros_docs(shape_name),
105
+ see_also_tag(shape_name),
106
+ ])
107
+ end
108
+
109
+ def eventstream_class_docs(shape_name)
110
+ join_docstrings([
111
+ html_to_markdown(Api.docstring(shape_name, @api)),
112
+ input_example_docs(shape_name),
113
+ eventstream_docs(shape_name),
114
+ see_also_tag(shape_name),
115
+ ])
116
+ end
117
+
118
+ def eventstream_docs(shape_name)
119
+ "EventStream is an Enumerator of Events.\n"\
120
+ " #event_types #=> Array, returns all modeled event types in the stream"
121
+ end
122
+
123
+ def input_example_docs(shape_name)
124
+ if @input_shapes.include?(shape_name)
125
+ return if shape(shape_name)['members'].nil?
126
+ if shape(shape_name)['members'].empty?
127
+ note = '@api private'
128
+ else
129
+ note = "@note When making an API call, you may pass #{shape_name}\n"
130
+ note += " data as a hash:\n\n"
131
+ note += ' ' + SyntaxExampleHash.new(
132
+ shape: shape(shape_name),
133
+ api: @service.api,
134
+ ).format(' ')
135
+ end
136
+ end
137
+ end
138
+
139
+ def attribute_macros_docs(shape_name)
140
+ # APIG model downcase shape name in origin or "__" prefix in origin
141
+ if @service.protocol == 'api-gateway'
142
+ if shape(shape_name).nil?
143
+ if !shape(downcase_first(shape_name)).nil?
144
+ shape_name = downcase_first(shape_name)
145
+ elsif !shape(apig_prefix(shape_name)).nil?
146
+ shape_name = apig_prefix(shape_name)
147
+ else
148
+ shape_name = apig_prefix(downcase_first(shape_name))
149
+ end
150
+ end
151
+ end
152
+ return if shape(shape_name)['members'].nil?
153
+ shape(shape_name)['members'].map do |member_name, member_ref|
154
+ docs = Api.docstring(member_ref, @api).to_s
155
+ docs += idempotency_token_msg if idempotency_token?(member_ref)
156
+ docs = html_to_markdown(docs, line_width: 68)
157
+ docs = docs.to_s.lines.to_a.join(' ')
158
+ macro = "@!attribute [rw] #{underscore(member_name)}\n"
159
+ macro += " #{docs}\n" unless docs == ''
160
+ macro += " @return [#{Api.ruby_type(member_ref, @api)}]"
161
+ macro
162
+ end
163
+ end
164
+
165
+ def see_also_tag(shape_name)
166
+ uid = @api['metadata']['uid']
167
+ if @api['metadata']['protocol'] != 'api-gateway' && Crosslink.taggable?(uid)
168
+ Crosslink.tag_string(uid, shape_name)
169
+ end
170
+ end
171
+
172
+ def compute_input_shapes(api)
173
+ inputs = Set.new
174
+ (api['operations'] || {}).each do |_, operation|
175
+ visit_inputs(operation['input'], inputs) if operation['input']
176
+ end
177
+ inputs
178
+ end
179
+
180
+ def idempotency_token?(member_ref)
181
+ member_ref['idempotencyToken'] || shape(member_ref)['idempotencyToken']
182
+ end
183
+
184
+ def idempotency_token_msg
185
+ "<p><b>A suitable default value is auto-generated.</b> You should normally not need to pass this option.</p>"
186
+ end
187
+
188
+ def visit_inputs(shape_ref, inputs)
189
+ return if inputs.include?(shape_ref['shape']) # recursion
190
+ inputs << shape_ref['shape']
191
+ s = shape(shape_ref)
192
+ raise "cannot locate shape #{shape_ref['shape']}" if s.nil?
193
+ case s['type']
194
+ when 'structure'
195
+ return if s['members'].nil?
196
+ s['members'].each_pair do |_, member_ref|
197
+ visit_inputs(member_ref, inputs)
198
+ end
199
+ when 'list'
200
+ visit_inputs(s['member'], inputs)
201
+ when 'map'
202
+ visit_inputs(s['key'], inputs)
203
+ visit_inputs(s['value'], inputs)
204
+ end
205
+ end
206
+
207
+ def shape(shape_ref)
208
+ Api.resolve(shape_ref, @api)[1]
209
+ end
210
+
211
+ class EventStreamClass
212
+
213
+ def initialize(options)
214
+ @class_name = options.fetch(:class_name)
215
+ @types = options.fetch(:types)
216
+ @documentation = options.fetch(:documentation)
217
+ if @types.nil? || @types.empty?
218
+ @empty = true
219
+ else
220
+ @empty = false
221
+ @types.last.last = true
222
+ end
223
+ end
224
+
225
+ # @return [String]
226
+ attr_accessor :class_name
227
+
228
+ # @return [Array<StructMember>]
229
+ attr_accessor :types
230
+
231
+ # @return [String, nil]
232
+ attr_accessor :documentation
233
+
234
+ # @return [Boolean]
235
+ def empty?
236
+ @empty
237
+ end
238
+
239
+ end
240
+
241
+ class StructClass
242
+
243
+ def initialize(options)
244
+ @class_name = options.fetch(:class_name)
245
+ @members = options.fetch(:members)
246
+ @documentation = options.fetch(:documentation)
247
+ @sensitive_params = options.fetch(:sensitive_params)
248
+ if @members.nil? || @members.empty?
249
+ @empty = true
250
+ else
251
+ @empty = false
252
+ @members.last.last = true
253
+ end
254
+ end
255
+
256
+ # @return [String]
257
+ attr_accessor :class_name
258
+
259
+ # @return [Array<StructMember>]
260
+ attr_accessor :members
261
+
262
+ # @return [String, nil]
263
+ attr_accessor :documentation
264
+
265
+ # @return [Array<Symbol>]
266
+ attr_accessor :sensitive_params
267
+
268
+ # @return [Boolean]
269
+ def empty?
270
+ @empty
271
+ end
272
+ end
273
+
274
+ class StructMember
275
+
276
+ def initialize(options)
277
+ @member_name = options.fetch(:member_name)
278
+ @sensitive = options.fetch(:sensitive, false)
279
+ @last = false
280
+ end
281
+
282
+ # @return [String]
283
+ attr_accessor :member_name
284
+
285
+ # @return [Boolean]
286
+ attr_accessor :sensitive
287
+
288
+ # @return [Boolean]
289
+ attr_accessor :last
290
+
291
+ end
292
+ end
293
+ end
294
+ end