Class: ElasticGraph::ProtoIngestion::SchemaDefinition::Schema

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb

Overview

Builds a proto2 or proto3 schema string from an ElasticGraph schema definition.

Constant Summary collapse

SUPPORTED_SYNTAXES =

Protobuf syntaxes this generator can emit.

%w[proto2 proto3].freeze
DEFAULT_SYNTAX =

The protobuf syntax emitted when the schema does not configure one.

"proto3"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(state:, all_types:, ingestion_state:) ⇒ Schema

Returns a new instance of Schema.

Parameters:

  • state (ElasticGraph::SchemaDefinition::State)
  • all_types (Array<ElasticGraph::SchemaDefinition::SchemaElements::graphQLType>)
  • ingestion_state (ProtoIngestionState)

    this extension's configured schema definition state



67
68
69
70
71
72
73
74
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 67

def initialize(state:, all_types:, ingestion_state:)
  @state = state
  @all_types = all_types
  @package_name = ingestion_state.package_name
  @syntax = self.class.validate_syntax(ingestion_state.syntax)
  @header_lines = self.class.validate_header_lines(ingestion_state.header_lines)
  @field_number_mappings = FieldNumberMappings.from_parsed_yaml(ingestion_state.field_number_mappings)
end

Class Method Details

.validate_header_lines(header_lines) ⇒ Array<String>

Validates configured header_lines, as validate_syntax does for a syntax.

Each element renders as its own line, so a newline in one element would silently produce more lines than the schema asked for.

Parameters:

  • header_lines (Array<String>)

Returns:

  • (Array<String>)


51
52
53
54
55
56
57
58
59
60
61
62
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 51

def self.validate_header_lines(header_lines)
  unless header_lines.is_a?(::Array) && header_lines.all?(::String)
    raise Errors::SchemaError, "`header_lines` must be an Array of Strings, got: #{header_lines.inspect}"
  end

  if (multi_line = header_lines.grep(/\n/)).any?
    raise Errors::SchemaError, "`header_lines` must not contain newlines, but got: #{multi_line.inspect}. " \
      "Pass one Array element per line."
  end

  header_lines
end

.validate_syntax(syntax) ⇒ String

Normalizes a configured syntax to one of SUPPORTED_SYNTAXES.

Both the proto_schema_artifacts API and this class validate through here so that a syntax is checked exactly once no matter which entry point supplies it.

Parameters:

  • syntax (Symbol, String)

Returns:

  • (String)


36
37
38
39
40
41
42
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 36

def self.validate_syntax(syntax)
  syntax.to_s.tap do |normalized|
    unless SUPPORTED_SYNTAXES.include?(normalized)
      raise Errors::SchemaError, "`syntax` must be one of #{SUPPORTED_SYNTAXES.inspect}, got: #{syntax.inspect}"
    end
  end
end

Instance Method Details

#field_label_prefix(repeated:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the label prefix (including its trailing space) that a field declaration needs under the configured syntax, or an empty string when the field takes no label.

proto2 requires an explicit label on every field, so non-repeated fields get optional; proto3 labels repeated fields only. Note that oneof alternatives never get a label under either syntax -- protoc rejects one -- so the oneof renderer in ObjectInterfaceAndUnionExtension does not call this.



132
133
134
135
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 132

def field_label_prefix(repeated:)
  return "repeated " if repeated
  proto2? ? "optional " : ""
end

#field_number_for(message_name:, type_name:, public_field_name:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the stable protobuf number for a message field.



106
107
108
109
110
111
112
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 106

def field_number_for(message_name:, type_name:, public_field_name:)
  @field_number_mappings.field_number_for(
    message_name: message_name,
    public_field_name: public_field_name,
    previous_field_names: previous_field_names_for(type_name, public_field_name)
  )
end

#field_number_mappings_for_artifactHash<String, Object>

Exposes the field-number and enum-value-number mappings for writing to artifact YAML.

Returns:

  • (Hash<String, Object>)


99
100
101
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 99

def field_number_mappings_for_artifact
  @field_number_mappings.to_dumpable_hash
end

#proto2?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Indicates whether the generator emits proto2 rather than proto3.

Returns:

  • (Boolean)


140
141
142
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 140

def proto2?
  @syntax == "proto2"
end

#to_protoString

Renders the schema as a valid file in the configured syntax.

Returns:

  • (String)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 79

def to_proto
  types = proto_types
  return "" if types.empty?

  validate_unique_enum_value_prefixes(types)

  sections = [
    %(syntax = "#{@syntax}";),
    "package #{@package_name};",
    *render_header_lines,
    *render_imports(types),
    render_definitions(types)
  ]

  sections.join("\n\n") + "\n"
end